From 71cb5fe5e75596b17a2a6f265496555c722a5724 Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:19:34 +0800 Subject: [PATCH 01/11] chore: seedless error with causes details --- .../src/SeedlessOnboardingController.ts | 8 ++- .../src/errors.ts | 72 +++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts index 5a91543ded0..858426038d8 100644 --- a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts +++ b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts @@ -38,7 +38,7 @@ import { SeedlessOnboardingControllerErrorMessage, Web3AuthNetwork, } from './constants'; -import { PasswordSyncError, RecoveryError } from './errors'; +import { PasswordSyncError, RecoveryError, SeedlessOnboardingError } from './errors'; import { projectLogger, createModuleLogger } from './logger'; import { SecretMetadata } from './SecretMetadata'; import type { @@ -437,8 +437,10 @@ export class SeedlessOnboardingController< return authenticationResult; } catch (error) { log('Error authenticating user', error); - throw new Error( - SeedlessOnboardingControllerErrorMessage.AuthenticationError, + throw new SeedlessOnboardingError( + SeedlessOnboardingControllerErrorMessage.AuthenticationError, { + cause: error instanceof Error ? error : new Error(error as string), + } ); } }; diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 7f5c0224de8..086064dc89b 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -135,3 +135,75 @@ export class RecoveryError extends Error { return new RecoveryError(errorMessage, recoveryErrorData); } } + +/** + * Generic error class for SeedlessOnboardingController operations. + * + * Use this when you need to wrap an underlying error with additional context, + * or when none of the more specific error classes (PasswordSyncError, RecoveryError) apply. + * + * @example + * ```typescript + * throw new SeedlessOnboardingError( + * SeedlessOnboardingControllerErrorMessage.FailedToEncryptAndStoreSecretData, + * { details: 'Encryption failed during backup', cause: originalError } + * ); + * ``` + */ +export class SeedlessOnboardingError extends Error { + /** + * Additional context about the error beyond the message. + * Use this for human-readable details that help with debugging. + */ + public details: string | undefined; + + /** + * The underlying error that caused this error. + */ + public cause: Error | undefined; + + constructor( + message: string | SeedlessOnboardingControllerErrorMessage, + options?: { details?: string; cause?: Error }, + ) { + super(message); + this.name = 'SeedlessOnboardingControllerError'; + this.details = options?.details; + this.cause = options?.cause; + } + + /** + * Creates a SeedlessOnboardingError from an unknown error. + * + * @param error - The original error to wrap. + * @param message - The error message to use. + * @param details - Optional additional context. + * @returns A new SeedlessOnboardingError instance. + */ + static from( + error: unknown, + message: string | SeedlessOnboardingControllerErrorMessage, + details?: string, + ): SeedlessOnboardingError { + const cause = error instanceof Error ? error : undefined; + return new SeedlessOnboardingError(message, { details, cause }); + } + + /** + * Serializes the error for logging/transmission. + * Ensures custom properties are included in JSON output. + * + * @returns A JSON-serializable representation of the error. + */ + toJSON(): Record { + return { + name: this.name, + message: this.message, + details: this.details, + cause: this.cause instanceof Error + ? { name: this.cause.name, message: this.cause.message } + : this.cause, + stack: this.stack, + }; + } +} From 3f36d61c16ec127083a38b54b3aaacea4c153216 Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:37:40 +0800 Subject: [PATCH 02/11] fix: address comment --- packages/seedless-onboarding-controller/src/errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 086064dc89b..f11ff464657 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -185,7 +185,7 @@ export class SeedlessOnboardingError extends Error { message: string | SeedlessOnboardingControllerErrorMessage, details?: string, ): SeedlessOnboardingError { - const cause = error instanceof Error ? error : undefined; + const cause = error instanceof Error ? error : new Error(String(error)); return new SeedlessOnboardingError(message, { details, cause }); } From 8d8c7bf2e0848c996fa1a2d0dac303c25e26bccf Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Thu, 22 Jan 2026 12:51:26 +0800 Subject: [PATCH 03/11] fix: address comment --- .../src/SeedlessOnboardingController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts index 858426038d8..168e6b07098 100644 --- a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts +++ b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts @@ -439,7 +439,7 @@ export class SeedlessOnboardingController< log('Error authenticating user', error); throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.AuthenticationError, { - cause: error instanceof Error ? error : new Error(error as string), + cause: error instanceof Error ? error : new Error(String(error)), } ); } From e2e7213ff60625d80fb41b2134871d1b4c324fbb Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Thu, 22 Jan 2026 13:35:04 +0800 Subject: [PATCH 04/11] fix: remove from --- .../src/SeedlessOnboardingController.ts | 2 +- .../src/errors.ts | 27 ++++++------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts index 168e6b07098..62ffc6efba8 100644 --- a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts +++ b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts @@ -439,7 +439,7 @@ export class SeedlessOnboardingController< log('Error authenticating user', error); throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.AuthenticationError, { - cause: error instanceof Error ? error : new Error(String(error)), + cause: error, } ); } diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index f11ff464657..74af8d7400e 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -164,29 +164,18 @@ export class SeedlessOnboardingError extends Error { constructor( message: string | SeedlessOnboardingControllerErrorMessage, - options?: { details?: string; cause?: Error }, + options?: { details?: string; cause?: unknown }, ) { super(message); this.name = 'SeedlessOnboardingControllerError'; this.details = options?.details; - this.cause = options?.cause; - } - - /** - * Creates a SeedlessOnboardingError from an unknown error. - * - * @param error - The original error to wrap. - * @param message - The error message to use. - * @param details - Optional additional context. - * @returns A new SeedlessOnboardingError instance. - */ - static from( - error: unknown, - message: string | SeedlessOnboardingControllerErrorMessage, - details?: string, - ): SeedlessOnboardingError { - const cause = error instanceof Error ? error : new Error(String(error)); - return new SeedlessOnboardingError(message, { details, cause }); + if (options?.cause) { + if (options.cause instanceof Error) { + this.cause = options.cause; + } else { + this.cause = new Error(String(options.cause)); + } + } } /** From 2c17b453acdb6a973abbd449765842ca4c32298e Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Thu, 22 Jan 2026 14:36:59 +0800 Subject: [PATCH 05/11] fix: yarn lint --- .../src/SeedlessOnboardingController.ts | 11 ++++++++--- .../seedless-onboarding-controller/src/errors.ts | 13 +++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts index 62ffc6efba8..d20536b8c5e 100644 --- a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts +++ b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts @@ -38,7 +38,11 @@ import { SeedlessOnboardingControllerErrorMessage, Web3AuthNetwork, } from './constants'; -import { PasswordSyncError, RecoveryError, SeedlessOnboardingError } from './errors'; +import { + PasswordSyncError, + RecoveryError, + SeedlessOnboardingError, +} from './errors'; import { projectLogger, createModuleLogger } from './logger'; import { SecretMetadata } from './SecretMetadata'; import type { @@ -438,9 +442,10 @@ export class SeedlessOnboardingController< } catch (error) { log('Error authenticating user', error); throw new SeedlessOnboardingError( - SeedlessOnboardingControllerErrorMessage.AuthenticationError, { + SeedlessOnboardingControllerErrorMessage.AuthenticationError, + { cause: error, - } + }, ); } }; diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 74af8d7400e..08befa59c94 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -173,7 +173,11 @@ export class SeedlessOnboardingError extends Error { if (options.cause instanceof Error) { this.cause = options.cause; } else { - this.cause = new Error(String(options.cause)); + const causeMessage = + typeof options.cause === 'string' + ? options.cause + : JSON.stringify(options.cause); + this.cause = new Error(causeMessage); } } } @@ -189,9 +193,10 @@ export class SeedlessOnboardingError extends Error { name: this.name, message: this.message, details: this.details, - cause: this.cause instanceof Error - ? { name: this.cause.name, message: this.cause.message } - : this.cause, + cause: + this.cause instanceof Error + ? { name: this.cause.name, message: this.cause.message } + : this.cause, stack: this.stack, }; } From d10aead6fd4999b304abd6f5567db1c7e5efbcc9 Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Thu, 22 Jan 2026 14:48:22 +0800 Subject: [PATCH 06/11] fix: address cursor comment --- .../seedless-onboarding-controller/src/errors.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 08befa59c94..4ae14dbbbec 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -173,10 +173,17 @@ export class SeedlessOnboardingError extends Error { if (options.cause instanceof Error) { this.cause = options.cause; } else { - const causeMessage = - typeof options.cause === 'string' - ? options.cause - : JSON.stringify(options.cause); + let causeMessage: string; + if (typeof options.cause === 'string') { + causeMessage = options.cause; + } else { + try { + causeMessage = JSON.stringify(options.cause); + } catch { + // Handle circular references, BigInt, or other non-serializable values + causeMessage = String(options.cause); + } + } this.cause = new Error(causeMessage); } } From e6ca21f4d59d6abf1b89a77416f0a5dd1fbb6100 Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Thu, 22 Jan 2026 16:16:40 +0800 Subject: [PATCH 07/11] fix: yarn lint --- packages/seedless-onboarding-controller/src/errors.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 4ae14dbbbec..8a6916ad05b 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -180,8 +180,7 @@ export class SeedlessOnboardingError extends Error { try { causeMessage = JSON.stringify(options.cause); } catch { - // Handle circular references, BigInt, or other non-serializable values - causeMessage = String(options.cause); + causeMessage = 'Unknown error'; } } this.cause = new Error(causeMessage); From a7d521fd884855c7eaeaf82b1e75a725834c27af Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:42:16 +0800 Subject: [PATCH 08/11] fix: export SeedlessOnboardingError class add testcases --- .../src/errors.test.ts | 161 +++++++++++++++++- .../src/index.ts | 2 +- 2 files changed, 161 insertions(+), 2 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/errors.test.ts b/packages/seedless-onboarding-controller/src/errors.test.ts index 0011a44c87f..795280022b0 100644 --- a/packages/seedless-onboarding-controller/src/errors.test.ts +++ b/packages/seedless-onboarding-controller/src/errors.test.ts @@ -1,7 +1,10 @@ import { TOPRFErrorCode } from '@metamask/toprf-secure-backup'; import { SeedlessOnboardingControllerErrorMessage } from './constants'; -import { getErrorMessageFromTOPRFErrorCode } from './errors'; +import { + getErrorMessageFromTOPRFErrorCode, + SeedlessOnboardingError, +} from './errors'; describe('getErrorMessageFromTOPRFErrorCode', () => { it('returns TooManyLoginAttempts for RateLimitExceeded', () => { @@ -49,3 +52,159 @@ describe('getErrorMessageFromTOPRFErrorCode', () => { ).toBe('fallback'); }); }); + +describe('SeedlessOnboardingError', () => { + describe('constructor', () => { + it('creates an error with just a message', () => { + const error = new SeedlessOnboardingError('Test error message'); + + expect(error.message).toBe('Test error message'); + expect(error.name).toBe('SeedlessOnboardingControllerError'); + expect(error.details).toBeUndefined(); + expect(error.cause).toBeUndefined(); + }); + + it('creates an error with a message from SeedlessOnboardingControllerErrorMessage enum', () => { + const error = new SeedlessOnboardingError( + SeedlessOnboardingControllerErrorMessage.AuthenticationError, + ); + + expect(error.message).toBe( + SeedlessOnboardingControllerErrorMessage.AuthenticationError, + ); + expect(error.name).toBe('SeedlessOnboardingControllerError'); + }); + + it('creates an error with message and details', () => { + const error = new SeedlessOnboardingError('Test error', { + details: 'Additional context for debugging', + }); + + expect(error.message).toBe('Test error'); + expect(error.details).toBe('Additional context for debugging'); + expect(error.cause).toBeUndefined(); + }); + + it('creates an error with an Error instance as cause', () => { + const originalError = new Error('Original error'); + const error = new SeedlessOnboardingError('Wrapped error', { + cause: originalError, + }); + + expect(error.message).toBe('Wrapped error'); + expect(error.cause).toBe(originalError); + }); + + it('creates an error with a string as cause', () => { + const error = new SeedlessOnboardingError('Test error', { + cause: 'String cause message', + }); + + expect(error.cause).toBeInstanceOf(Error); + expect(error.cause?.message).toBe('String cause message'); + }); + + it('creates an error with an object as cause (JSON serializable)', () => { + const causeObject = { code: 500, reason: 'Internal error' }; + const error = new SeedlessOnboardingError('Test error', { + cause: causeObject, + }); + + expect(error.cause).toBeInstanceOf(Error); + expect(error.cause?.message).toBe(JSON.stringify(causeObject)); + }); + + it('handles circular object as cause by using fallback message', () => { + const circularObject: Record = { name: 'circular' }; + circularObject.self = circularObject; + + const error = new SeedlessOnboardingError('Test error', { + cause: circularObject, + }); + + expect(error.cause).toBeInstanceOf(Error); + expect(error.cause?.message).toBe('Unknown error'); + }); + + it('creates an error with both details and cause', () => { + const originalError = new Error('Original'); + const error = new SeedlessOnboardingError('Test error', { + details: 'Some details', + cause: originalError, + }); + + expect(error.message).toBe('Test error'); + expect(error.details).toBe('Some details'); + expect(error.cause).toBe(originalError); + }); + }); + + describe('toJSON', () => { + it('serializes error with all properties', () => { + const originalError = new Error('Original error'); + const error = new SeedlessOnboardingError('Test error', { + details: 'Debug info', + cause: originalError, + }); + + const json = error.toJSON(); + + expect(json.name).toBe('SeedlessOnboardingControllerError'); + expect(json.message).toBe('Test error'); + expect(json.details).toBe('Debug info'); + expect(json.cause).toStrictEqual({ + name: 'Error', + message: 'Original error', + }); + expect(json.stack).toBeDefined(); + }); + + it('serializes error without optional properties', () => { + const error = new SeedlessOnboardingError('Simple error'); + + const json = error.toJSON(); + + expect(json.name).toBe('SeedlessOnboardingControllerError'); + expect(json.message).toBe('Simple error'); + expect(json.details).toBeUndefined(); + expect(json.cause).toBeUndefined(); + expect(json.stack).toBeDefined(); + }); + + it('serializes error with custom error type as cause', () => { + class CustomError extends Error { + constructor() { + super('Custom error message'); + this.name = 'CustomError'; + } + } + const customError = new CustomError(); + const error = new SeedlessOnboardingError('Wrapper', { + cause: customError, + }); + + const json = error.toJSON(); + + expect(json.cause).toStrictEqual({ + name: 'CustomError', + message: 'Custom error message', + }); + }); + }); + + describe('inheritance', () => { + it('is an instance of Error', () => { + const error = new SeedlessOnboardingError('Test'); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(SeedlessOnboardingError); + }); + + it('has a proper stack trace', () => { + const error = new SeedlessOnboardingError('Test'); + + expect(error.stack).toBeDefined(); + expect(error.stack).toContain('SeedlessOnboardingError'); + }); + }); +}); diff --git a/packages/seedless-onboarding-controller/src/index.ts b/packages/seedless-onboarding-controller/src/index.ts index 4d445795530..1cdde0d2a84 100644 --- a/packages/seedless-onboarding-controller/src/index.ts +++ b/packages/seedless-onboarding-controller/src/index.ts @@ -22,4 +22,4 @@ export { SecretType, } from './constants'; export { SecretMetadata } from './SecretMetadata'; -export { RecoveryError } from './errors'; +export { RecoveryError, SeedlessOnboardingError } from './errors'; From ab4b842f92558f28a6c41b563c8e5d4ac04e7ff5 Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:29:49 +0800 Subject: [PATCH 09/11] fix: cursor comment --- .../src/errors.test.ts | 48 ++++++++++++++++++- .../src/errors.ts | 8 ++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/errors.test.ts b/packages/seedless-onboarding-controller/src/errors.test.ts index 795280022b0..e090e16a648 100644 --- a/packages/seedless-onboarding-controller/src/errors.test.ts +++ b/packages/seedless-onboarding-controller/src/errors.test.ts @@ -190,6 +190,52 @@ describe('SeedlessOnboardingError', () => { message: 'Custom error message', }); }); + + it('serializes SeedlessOnboardingError cause with details preserved', () => { + const innerError = new SeedlessOnboardingError('Inner error', { + details: 'Inner debugging context', + }); + const outerError = new SeedlessOnboardingError('Outer error', { + details: 'Outer debugging context', + cause: innerError, + }); + + const json = outerError.toJSON(); + + expect(json.name).toBe('SeedlessOnboardingControllerError'); + expect(json.message).toBe('Outer error'); + expect(json.details).toBe('Outer debugging context'); + expect(json.cause).toStrictEqual({ + name: 'SeedlessOnboardingControllerError', + message: 'Inner error', + details: 'Inner debugging context', + cause: undefined, + stack: innerError.stack, + }); + }); + + it('serializes deeply nested SeedlessOnboardingError chain', () => { + const rootError = new Error('Root cause'); + const level1 = new SeedlessOnboardingError('Level 1', { + details: 'Level 1 details', + cause: rootError, + }); + const level2 = new SeedlessOnboardingError('Level 2', { + details: 'Level 2 details', + cause: level1, + }); + + const json = level2.toJSON(); + + expect(json.details).toBe('Level 2 details'); + const level1Json = json.cause as Record; + expect(level1Json.message).toBe('Level 1'); + expect(level1Json.details).toBe('Level 1 details'); + expect(level1Json.cause).toStrictEqual({ + name: 'Error', + message: 'Root cause', + }); + }); }); describe('inheritance', () => { @@ -204,7 +250,7 @@ describe('SeedlessOnboardingError', () => { const error = new SeedlessOnboardingError('Test'); expect(error.stack).toBeDefined(); - expect(error.stack).toContain('SeedlessOnboardingError'); + expect(error.stack).toContain('SeedlessOnboardingControllerError'); }); }); }); diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 8a6916ad05b..35f2b2c29d6 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -200,9 +200,11 @@ export class SeedlessOnboardingError extends Error { message: this.message, details: this.details, cause: - this.cause instanceof Error - ? { name: this.cause.name, message: this.cause.message } - : this.cause, + this.cause instanceof SeedlessOnboardingError + ? this.cause.toJSON() + : this.cause instanceof Error + ? { name: this.cause.name, message: this.cause.message } + : this.cause, stack: this.stack, }; } From b66a50f77058bc46bad67aae42ed665cf9abdaeb Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:29:34 +0800 Subject: [PATCH 10/11] fix: linting --- .../src/errors.ts | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/errors.ts b/packages/seedless-onboarding-controller/src/errors.ts index 35f2b2c29d6..005a614cdb6 100644 --- a/packages/seedless-onboarding-controller/src/errors.ts +++ b/packages/seedless-onboarding-controller/src/errors.ts @@ -188,6 +188,21 @@ export class SeedlessOnboardingError extends Error { } } + /** + * Serializes the cause error for JSON output. + * + * @returns A JSON-serializable representation of the cause. + */ + #serializeCause(): Record | undefined { + if (this.cause instanceof SeedlessOnboardingError) { + return this.cause.toJSON(); + } + if (this.cause instanceof Error) { + return { name: this.cause.name, message: this.cause.message }; + } + return undefined; + } + /** * Serializes the error for logging/transmission. * Ensures custom properties are included in JSON output. @@ -199,12 +214,7 @@ export class SeedlessOnboardingError extends Error { name: this.name, message: this.message, details: this.details, - cause: - this.cause instanceof SeedlessOnboardingError - ? this.cause.toJSON() - : this.cause instanceof Error - ? { name: this.cause.name, message: this.cause.message } - : this.cause, + cause: this.#serializeCause(), stack: this.stack, }; } From 543249ddf8a7bd4170af86c882601e1657842144 Mon Sep 17 00:00:00 2001 From: ieow <4881057+ieow@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:44:51 +0800 Subject: [PATCH 11/11] feat: bubble up error that need more info --- .../src/SeedlessOnboardingController.ts | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts index d20536b8c5e..5b3c11f0001 100644 --- a/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts +++ b/packages/seedless-onboarding-controller/src/SeedlessOnboardingController.ts @@ -671,8 +671,11 @@ export class SeedlessOnboardingController< ); } catch (error) { log('Error changing password', error); - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.FailedToChangePassword, + { + cause: error, + }, ); } }); @@ -948,8 +951,11 @@ export class SeedlessOnboardingController< }) .catch((error) => { log('Error fetching auth pub key', error); - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.FailedToFetchAuthPubKey, + { + cause: error, + }, ); }); globalAuthPubKey = authPubKey; @@ -1038,8 +1044,11 @@ export class SeedlessOnboardingController< throw error; } log('Error persisting local encryption key', error); - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.FailedToPersistOprfKey, + { + cause: error, + }, ); } } @@ -1202,8 +1211,11 @@ export class SeedlessOnboardingController< if (this.#isAuthTokenError(error)) { throw error; } - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.FailedToFetchSecretMetadata, + { + cause: error, + }, ); } @@ -1812,8 +1824,11 @@ export class SeedlessOnboardingController< }) .catch((error) => { log('Error fetching auth pub key', error); - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.FailedToFetchAuthPubKey, + { + cause: error, + }, ); }); const isPasswordOutdated = await this.checkIsPasswordOutdated({ @@ -1851,8 +1866,11 @@ export class SeedlessOnboardingController< refreshToken, }).catch((error) => { log('Error refreshing JWT tokens', error); - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.FailedToRefreshJWTTokens, + { + cause: error, + }, ); }); @@ -1873,8 +1891,11 @@ export class SeedlessOnboardingController< }); } catch (error) { log('Error refreshing node auth tokens', error); - throw new Error( + throw new SeedlessOnboardingError( SeedlessOnboardingControllerErrorMessage.AuthenticationError, + { + cause: error, + }, ); } }