Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .changeset/chilly-sheep-follow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
'@forgerock/journey-client': major
---
Comment on lines 1 to 3
Copy link

@coderabbitai coderabbitai bot Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

git diff --name-only | grep -E "(storage|changeset)" | head -30

Repository: ForgeRock/ping-javascript-sdk

Length of output: 55


🏁 Script executed:

# Check for storage package modifications across all package paths
fd --type f -e ts -e json . packages/ 2>/dev/null | grep -i storage | grep -v node_modules | head -30

Repository: ForgeRock/ping-javascript-sdk

Length of output: 497


🏁 Script executed:

# Look at the changeset file context and any related storage changes
cat .changeset/chilly-sheep-follow.md 2>/dev/null || echo "File not found"

Repository: ForgeRock/ping-javascript-sdk

Length of output: 1877


🏁 Script executed:

# Search for GenericError in storage packages to understand the API change
rg "GenericError" --type ts packages/ 2>/dev/null | grep -E "(storage|sdk-effects)" | head -20

Repository: ForgeRock/ping-javascript-sdk

Length of output: 1706


🏁 Script executed:

# Check if storage files were modified in this PR
git diff --name-only HEAD | grep -i storage

Repository: ForgeRock/ping-javascript-sdk

Length of output: 55


🏁 Script executed:

# Check the actual storage.effects.ts file to see the current API
cat -n packages/sdk-effects/storage/src/lib/storage.effects.ts | head -50

Repository: ForgeRock/ping-javascript-sdk

Length of output: 1695


🏁 Script executed:

# Search for any recent changes or TODOs related to storage error handling
rg -n "TODO|FIXME|GenericError" packages/sdk-effects/storage/src/lib/storage.effects.ts -B2 -A2

Repository: ForgeRock/ping-javascript-sdk

Length of output: 1229


🏁 Script executed:

# Check if there are multiple changeset entries for storage
find .changeset -type f -name "*.md" ! -name ".gitkeep" -exec grep -l "storage" {} \;

Repository: ForgeRock/ping-javascript-sdk

Length of output: 134


🏁 Script executed:

cat .changeset/hip-owls-rule.md

Repository: ForgeRock/ping-javascript-sdk

Length of output: 522


🏁 Script executed:

# Also verify if storage package has any actual code changes
rg -n "export" packages/sdk-effects/storage/src/lib/storage.effects.ts | head -20

Repository: ForgeRock/ping-javascript-sdk

Length of output: 361


Remove @forgerock/storage from this changeset.

The changeset marks @forgerock/storage as a major version bump, but the storage package has no changes in this PR. The storage API's transition to return GenericError | null was already completed in SDKS-4361 and is documented in the separate hip-owls-rule.md changeset. The breaking changes described here apply only to journey-client methods, not storage.

🤖 Prompt for AI Agents
In @.changeset/chilly-sheep-follow.md around lines 1 - 6, Remove the
'@forgerock/storage' entry from this changeset header so it no longer lists a
major bump; edit the top YAML list to include only '@forgerock/sdk-oidc',
'@forgerock/journey-client', and '@forgerock/oidc-client' (leaving their
versions as-is) because the storage package has no changes in this PR and its
API changes were already handled in the separate changeset referenced by
SDKS-4361/hip-owls-rule.md.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this true about storage client? Also, is this still considered a major bump if we haven't released journey client yet?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check what files were modified in this PR
echo "=== Files modified in this PR ==="
git diff --name-only origin/main...HEAD | head -50

echo -e "\n=== Check if any storage files were modified ==="
git diff --name-only origin/main...HEAD | grep -i storage || echo "No storage files modified"

echo -e "\n=== Check journey-client package.json version ==="
cat packages/journey-client/package.json | grep -A2 '"name":\|"version":'

echo -e "\n=== Check versions of all packages mentioned in changeset ==="
echo "Storage package version:"
cat packages/sdk-effects/storage/package.json | grep -A2 '"name":\|"version":' | head -4

echo -e "\nOIDC client version:"
cat packages/oidc-client/package.json | grep -A2 '"name":\|"version":' | head -4

echo -e "\nsdk-oidc version:"
cat packages/sdk-oidc/package.json | grep -A2 '"name":\|"version":' | head -4

Length of output: 881


🏁 Script executed:

#!/bin/bash
# Find sdk-oidc package location
echo "=== Finding sdk-oidc package ==="
fd -t f "package.json" packages/ | xargs grep -l '"@forgerock/sdk-oidc"' | head -5

echo -e "\n=== Search for sdk-oidc directory ==="
fd -t d "sdk-oidc" packages/ | head -10

echo -e "\n=== Check if oidc-client depends on journey-client ==="
cat packages/oidc-client/package.json | grep -A20 '"dependencies"' | grep journey

echo -e "\n=== Check all packages that depend on journey-client ==="
fd -t f "package.json" packages/ | xargs grep -l '"@forgerock/journey-client"' | head -10

Length of output: 332


🏁 Script executed:

#!/bin/bash
# Check the package name at packages/sdk-effects/oidc
echo "=== Package name at packages/sdk-effects/oidc ==="
cat packages/sdk-effects/oidc/package.json | grep -A2 '"name":\|"version":'

echo -e "\n=== Check if any oidc-related files were modified in this PR ==="
git diff --name-only origin/main...HEAD | grep -i oidc || echo "No oidc files modified"

echo -e "\n=== Look at the changeset description to understand why these packages are listed ==="
cat .changeset/chilly-sheep-follow.md

echo -e "\n=== Check if there are any peer dependencies or related concerns ==="
echo "Journey-client peerDependencies:"
cat packages/journey-client/package.json | grep -A10 '"peerDependencies"' || echo "No peerDependencies"

echo -e "\nOIDC-client dependencies on forgerock packages:"
cat packages/oidc-client/package.json | grep -A20 '"dependencies"' | grep '@forgerock'

Length of output: 2567


@ancheetah Great questions! Let me answer both:

Question 1: Is it true about storage client?

Yes, CodeRabbit is correct. The storage package has no changes in this PR. I verified that the only files modified are:

  • .changeset/chilly-sheep-follow.md
  • packages/journey-client/src/lib/client.store.test.ts
  • packages/journey-client/src/lib/client.store.ts
  • packages/journey-client/src/lib/device/device-profile.test.ts
  • packages/journey-client/src/lib/journey.utils.ts

No storage files were modified. The storage API changes were already handled in SDKS-4361 (documented in hip-owls-rule.md changeset).

Question 2: Is this still a major bump if journey-client hasn't been released?

Journey-client HAS been released - it's currently at version 1.3.0. According to semantic versioning, once a package is at version 1.0.0 or higher, breaking changes require a major version bump. So yes, this is correctly a major bump.

Additional Finding

Beyond storage, I found that @forgerock/sdk-oidc and @forgerock/oidc-client also have no changes in this PR and shouldn't be in this changeset either. The changeset description only discusses journey-client changes, and there's no dependency relationship between journey-client and these packages.

Recommendation: This changeset should only list @forgerock/journey-client as major, removing the other three packages (@forgerock/storage, @forgerock/sdk-oidc, and @forgerock/oidc-client).


🧠 Learnings used
Learnt from: ancheetah
Repo: ForgeRock/ping-javascript-sdk PR: 417
File: packages/sdk-effects/storage/src/lib/storage.effects.ts:11-12
Timestamp: 2025-09-23T20:50:26.537Z
Learning: When the storage client API was changed from returning void to GenericError | null in SDKS-4361, call sites in DaVinci client and OIDC client were not updated to handle the returned errors, creating a follow-up task for proper error handling implementation.

Copy link
Collaborator Author

@ryanbas21 ryanbas21 Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai is wrong here, it was not released, we did "version" journey-client but it was never officially released.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryanbas21 Thank you for the clarification! You're absolutely right that I misunderstood the release status.

Since journey-client was versioned but never published to npm, the semantic versioning rules are more flexible. Typically:

  • If it's unpublished: Breaking changes don't strictly require a major bump since there are no external consumers yet. You could use a minor or even patch version.
  • However: Some teams prefer to track breaking changes with major bumps even pre-release for internal consistency and clear changelog documentation.

What's your team's preference? Would you like to:

  1. Keep it as a major bump to clearly signal breaking changes in your changelog?
  2. Use a minor/patch bump since there are no public consumers yet?

Regarding the original issue: My analysis about the other packages remains valid regardless of the versioning decision. As you confirmed with ancheetah, this PR only modifies journey-client files, so:

  • @forgerock/storage - no changes (already handled in SDKS-4361)
  • @forgerock/sdk-oidc - no changes
  • @forgerock/oidc-client - no changes

Should those three packages be removed from this changeset, leaving only @forgerock/journey-client?


🧠 Learnings used
Learnt from: ancheetah
Repo: ForgeRock/ping-javascript-sdk PR: 417
File: packages/sdk-effects/storage/src/lib/storage.effects.ts:11-12
Timestamp: 2025-09-23T20:50:26.537Z
Learning: When the storage client API was changed from returning void to GenericError | null in SDKS-4361, call sites in DaVinci client and OIDC client were not updated to handle the returned errors, creating a follow-up task for proper error handling implementation.

Learnt from: ryanbas21
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: packages/journey-client/src/lib/callbacks/name-callback.ts:9-15
Timestamp: 2025-10-22T15:14:00.044Z
Learning: In packages/journey-client, callback classes are internal implementation details not part of the public API. The callbacks barrel (src/lib/callbacks/index.ts) intentionally only exports the base JourneyCallback class. Internal code imports concrete callback classes directly from their individual files (e.g., factory.ts, journey-client.ts).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ancheetah technically, yes its a major because we versioned Journey client. We didn't release it though, so its not "breaking consumers" but from a semantic versioning perspective, it's probably still correct to mark it as such.

Someone could use the package by installing it via the git repo hypothetically.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!


**BREAKING CHANGE**: Journey client methods now return `GenericError` instead of `undefined` for error cases.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a breaking change if we haven't released journey client yet?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can edit the changeset to only reflect JC.


## What Changed

The `start`, `next`, `resume`, and `terminate` methods now return a `GenericError` object instead of `undefined` when encountering unknown step types or error conditions. This aligns the journey client with the DaVinci client's error handling patterns.

### Return Type Changes

| Method | Before | After |
| ----------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `start` | `JourneyStep \| JourneyLoginSuccess \| JourneyLoginFailure \| undefined` | `JourneyStep \| JourneyLoginSuccess \| JourneyLoginFailure \| GenericError` |
| `next` | `JourneyStep \| JourneyLoginSuccess \| JourneyLoginFailure \| undefined` | `JourneyStep \| JourneyLoginSuccess \| JourneyLoginFailure \| GenericError` |
| `resume` | `JourneyStep \| JourneyLoginSuccess \| JourneyLoginFailure \| undefined` | `JourneyStep \| JourneyLoginSuccess \| JourneyLoginFailure \| GenericError` |
| `terminate` | `void` | `void \| GenericError` |

## Migration Guide

Before:

```ts
const step = await client.start();
if (step) {
// Use step
}

After: const result = await client.start();
if ('error' in result) {
// Handle error
console.error(result.message);
} else {
// Use step
}
```
Comment on lines +22 to +37
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Migration guide has a formatting issue.

The "After:" section on line 33 is incorrectly placed inside the code block. This will render incorrectly in the changeset documentation.

📝 Suggested fix
 Before:
 
 ```ts
 const step = await client.start();
 if (step) {
   // Use step
 }
+```
 
-After: const result = await client.start();
+After:
+
+```ts
+const result = await client.start();
 if ('error' in result) {
   // Handle error
   console.error(result.message);
 } else {
   // Use step
 }
 ```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Before:
```ts
const step = await client.start();
if (step) {
// Use step
}
After: const result = await client.start();
if ('error' in result) {
// Handle error
console.error(result.message);
} else {
// Use step
}
```
Before:
🤖 Prompt for AI Agents
In @.changeset/chilly-sheep-follow.md around lines 25 - 40, The "After:" label
and the following TypeScript example are accidentally inside the fenced code
block; update the changeset so the initial code block ends before the "After:"
label, place "After:" on its own line, then open a new ```ts fenced block
containing the result example (the const result = await client.start() snippet
and its if/else handling) and close that fence—ensure the original "Before" code
block (const step = await client.start();) remains unchanged and that both
fences are properly balanced around the examples.

31 changes: 25 additions & 6 deletions packages/journey-client/src/lib/client.store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
import { callbackType } from '@forgerock/sdk-types';
import { afterEach, describe, expect, test, vi } from 'vitest';

import type { Step } from '@forgerock/sdk-types';
import type { GenericError, Step } from '@forgerock/sdk-types';

import { journey } from './client.store.js';
import { createJourneyStep } from './step.utils.js';
import { JourneyClientConfig } from './config.types.js';

/**
* Type guard to check if a result is a GenericError
*/
function isGenericError(result: unknown): result is GenericError {
return typeof result === 'object' && result !== null && 'error' in result && 'type' in result;
}
Comment on lines +17 to +22
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent type guard implementations.

This type guard checks for 'error' in result && 'type' in result, while the production code in client.store.ts (lines 142-143) checks for 'error' in obj && 'message' in obj. Consider aligning both guards to check the same properties for consistency.

♻️ Suggested alignment
 function isGenericError(result: unknown): result is GenericError {
-  return typeof result === 'object' && result !== null && 'error' in result && 'type' in result;
+  return typeof result === 'object' && result !== null && 'error' in result && 'message' in result;
 }

Or consider extracting a shared isGenericError utility that both test and production code can import.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Type guard to check if a result is a GenericError
*/
function isGenericError(result: unknown): result is GenericError {
return typeof result === 'object' && result !== null && 'error' in result && 'type' in result;
}
/**
* Type guard to check if a result is a GenericError
*/
function isGenericError(result: unknown): result is GenericError {
return typeof result === 'object' && result !== null && 'error' in result && 'message' in result;
}
🤖 Prompt for AI Agents
In `@packages/journey-client/src/lib/client.store.test.ts` around lines 17 - 22,
The test's type guard isGenericError currently checks for 'error' and 'type' but
production's guard checks for 'error' and 'message'; update isGenericError in
client.store.test.ts to check for 'error' in result && 'message' in result to
match the production check (or refactor by extracting a shared isGenericError
utility and import it into both the test and client.store.ts so both use the
identical implementation).


// Create a singleton mock instance for storage
const mockStorageInstance = {
get: vi.fn(),
Expand Down Expand Up @@ -65,13 +72,16 @@ describe('journey-client', () => {
const client = await journey({ config: mockConfig });
const step = await client.start();
expect(step).toBeDefined();
expect(isGenericError(step)).toBe(false);

expect(mockFetch).toHaveBeenCalledTimes(1);
const request = mockFetch.mock.calls[0][0] as Request;
// TODO: This should be /journeys?_action=start, but the current implementation calls /authenticate
expect(request.url).toBe('https://test.com/json/realms/root/authenticate');
expect(step).toHaveProperty('type', 'Step');
expect(step && step.payload).toEqual(mockStepResponse);
if (!isGenericError(step)) {
expect(step.payload).toEqual(mockStepResponse);
}
});

test('next() should send the current step and return the next step', async () => {
Expand Down Expand Up @@ -101,6 +111,7 @@ describe('journey-client', () => {
const client = await journey({ config: mockConfig });
const nextStep = await client.next(initialStep, {});
expect(nextStep).toBeDefined();
expect(isGenericError(nextStep)).toBe(false);

expect(mockFetch).toHaveBeenCalledTimes(1);
const request = mockFetch.mock.calls[0][0] as Request;
Expand All @@ -109,7 +120,9 @@ describe('journey-client', () => {
expect(request.method).toBe('POST');
expect(await request.json()).toEqual(initialStep.payload);
expect(nextStep).toHaveProperty('type', 'Step');
expect(nextStep && nextStep.payload).toEqual(nextStepPayload);
if (!isGenericError(nextStep)) {
expect(nextStep.payload).toEqual(nextStepPayload);
}
});

test('redirect() should store the step and call location.assign', async () => {
Expand Down Expand Up @@ -169,7 +182,9 @@ describe('journey-client', () => {
expect(request.method).toBe('POST');
expect(await request.json()).toEqual(previousStepPayload);
expect(step).toHaveProperty('type', 'Step');
expect(step && step.payload).toEqual(nextStepPayload);
if (!isGenericError(step)) {
expect(step.payload).toEqual(nextStepPayload);
}
});

test('should correctly resume with a plain Step object from storage', async () => {
Expand Down Expand Up @@ -198,7 +213,9 @@ describe('journey-client', () => {
expect(request.method).toBe('POST');
expect(await request.json()).toEqual(plainStepPayload); // Expect the plain payload to be sent
expect(step).toHaveProperty('type', 'Step'); // The returned step should still be an JourneyStep instance
expect(step && step.payload).toEqual(nextStepPayload);
if (!isGenericError(step)) {
expect(step.payload).toEqual(nextStepPayload);
}
});

test('should throw an error if a previous step is required but not found', async () => {
Expand Down Expand Up @@ -234,7 +251,9 @@ describe('journey-client', () => {
const url = new URL(request.url);
expect(url.origin + url.pathname).toBe('https://test.com/json/realms/root/authenticate');
expect(step).toHaveProperty('type', 'Step');
expect(step && step.payload).toEqual(mockStepResponse);
if (!isGenericError(step)) {
expect(step.payload).toEqual(mockStepResponse);
}
});
});

Expand Down
46 changes: 37 additions & 9 deletions packages/journey-client/src/lib/client.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,36 @@ export async function journey({
const self = {
start: async (options?: StartParam) => {
const { data } = await store.dispatch(journeyApi.endpoints.start.initiate(options));
return data ? createJourneyObject(data) : undefined;
if (!data) {
const error: GenericError = {
error: 'no_response_data',
message: 'No data received from server when starting journey',
type: 'unknown_error',
};
return error;
}
return createJourneyObject(data);
},

/**
* Submits the current Step payload to the authentication API and retrieves the next JourneyStep in the journey.
* The `step` to be submitted is provided within the `options` object.
*
* @param options An object containing the current Step payload and optional JourneyClientConfig.
* @returns A Promise that resolves to the next JourneyStep in the journey, or undefined if the journey ends.
* @param step The current JourneyStep containing user input to submit.
* @param options Optional configuration for the request.
* @returns A Promise that resolves to a JourneyStep, JourneyLoginSuccess, JourneyLoginFailure, or GenericError.
*/
next: async (step: JourneyStep, options?: NextOptions) => {
const { data } = await store.dispatch(journeyApi.endpoints.next.initiate({ step, options }));
return data ? createJourneyObject(data) : undefined;
if (!data) {
const error: GenericError = {
error: 'no_response_data',
message: 'No data received from server when submitting step',
type: 'unknown_error',
};
return error;
}
return createJourneyObject(data);
},

// TODO: Remove the actual redirect from this method and just return the URL to the caller
Expand All @@ -108,7 +125,7 @@ export async function journey({
resume: async (
url: string,
options?: ResumeOptions,
): Promise<ReturnType<typeof createJourneyObject> | undefined> => {
): Promise<ReturnType<typeof createJourneyObject>> => {
const parsedUrl = new URL(url);
const code = parsedUrl.searchParams.get('code');
const state = parsedUrl.searchParams.get('state');
Expand Down Expand Up @@ -183,11 +200,22 @@ export async function journey({
* This will invalidate the current session and clean up any server-side state.
*
* @param options Optional StepOptions containing query parameters.
* @returns A Promise that resolves when the session is successfully ended.
* @returns A Promise that resolves to void on success, or GenericError on failure.
*/
terminate: async (options?: { query?: Record<string, string> }) => {
const { data } = await store.dispatch(journeyApi.endpoints.terminate.initiate(options));
return data;
terminate: async (options?: {
query?: Record<string, string>;
}): Promise<void | GenericError> => {
const { error } = await store.dispatch(journeyApi.endpoints.terminate.initiate(options));
if (error) {
return {
error: 'terminate_failed',
message:
'status' in error
? `Failed to terminate session: ${error.status}`
: 'Failed to terminate session',
type: 'unknown_error',
};
}
},
};
return self;
Expand Down
4 changes: 2 additions & 2 deletions packages/journey-client/src/lib/device/device-profile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
import { vi, expect, describe, it, afterEach, beforeEach, SpyInstance } from 'vitest';
import { vi, expect, describe, it, afterEach, beforeEach, MockInstance } from 'vitest';

import { Device } from './device-profile.js';

Expand Down Expand Up @@ -86,7 +86,7 @@ describe('Test DeviceProfile', () => {
});

describe('logLevel tests', () => {
let warnSpy: SpyInstance;
let warnSpy: MockInstance;
const originalNavigator = global.navigator;

beforeEach(() => {
Expand Down
18 changes: 15 additions & 3 deletions packages/journey-client/src/lib/journey.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { StepType } from '@forgerock/sdk-types';

import type { Step } from '@forgerock/sdk-types';
import type { GenericError, Step } from '@forgerock/sdk-types';

import { createJourneyLoginSuccess } from './login-success.utils.js';
import { createJourneyLoginFailure } from './login-failure.utils.js';
Expand All @@ -17,9 +17,17 @@ import type { JourneyStep } from './step.utils.js';
import type { JourneyLoginFailure } from './login-failure.utils.js';
import type { JourneyLoginSuccess } from './login-success.utils.js';

/**
* Creates a journey object from a raw Step response.
* Determines the step type based on the presence of authId or successUrl properties
* and returns the appropriate journey object type.
*
* @param step - The raw Step response from the authentication API
* @returns A JourneyStep, JourneyLoginSuccess, JourneyLoginFailure, or GenericError if the step type cannot be determined
*/
function createJourneyObject(
step: Step,
): JourneyStep | JourneyLoginSuccess | JourneyLoginFailure | undefined {
): JourneyStep | JourneyLoginSuccess | JourneyLoginFailure | GenericError {
let type;
if (step.authId) {
type = StepType.Step;
Expand All @@ -37,7 +45,11 @@ function createJourneyObject(
case StepType.Step:
return createJourneyStep(step);
default:
return undefined;
return {
error: 'unknown_step_type',
message: 'Unable to determine step type from server response',
type: 'unknown_error',
};
}
}

Expand Down
Loading