Skip to content
Open
Changes from 4 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
53 changes: 51 additions & 2 deletions packages/keychain/src/components/ErrorAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ export function ControllerErrorAlert({
: error.message;
} else {
title = "Unknown error";
description = error.message;
description = error.message || serializeErrorDetails(error);
copyText = serializeErrorDetails(error);
isExpanded = true;
}

return (
Expand Down Expand Up @@ -359,7 +361,9 @@ export function ControllerErrorAlert({
break;
case ErrorCode.StarknetUnexpectedError:
title = "Unexpected Error";
description = error.data?.reason || JSON.stringify(error);
description = error.data?.reason || serializeErrorDetails(error);
isExpanded = true;
copyText = serializeErrorDetails(error);
break;
case ErrorCode.StarknetTransactionExecutionError:
try {
Expand Down Expand Up @@ -395,6 +399,9 @@ export function ControllerErrorAlert({
}
default: {
title = "Unknown Error";
description = serializeErrorDetails(error);
isExpanded = true;
copyText = serializeErrorDetails(error);
break;
}
}
Expand Down Expand Up @@ -494,3 +501,45 @@ export function humanizeString(str: string): string {
.replace(/^\w/, (c) => c.toUpperCase())
);
}

/**
* Serializes error details including all enumerable properties
* This is especially useful for WASM/Rust errors that may have additional fields
*/
export function serializeErrorDetails(error: unknown): string {
const errorObj: Record<string, unknown> = {};

// Type guard to ensure error is an object
if (typeof error !== "object" || error === null) {
return String(error);
}

// Get all enumerable properties from the error
for (const key in error) {
try {
const value = (error as Record<string, unknown>)[key];
// Skip functions and undefined values
if (typeof value !== "function" && value !== undefined) {
errorObj[key] = value;
}
} catch () {
// Skip properties that throw errors when accessed
continue;
}
}

// Also try to get standard Error properties that might not be enumerable
const err = error as Partial<Error>;
if (err.message && !errorObj.message) {
errorObj.message = err.message;
}
if (err.name && !errorObj.name) {
errorObj.name = err.name;
}
if (err.stack && !errorObj.stack) {
errorObj.stack = err.stack;
}

// Format as a readable string
return JSON.stringify(errorObj, null, 2);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Circular references break JSON error serialization display

The serializeErrorDetails function uses JSON.stringify, which can fail when error objects contain circular references or non-serializable values. This prevents the error display from showing any information to the user.

Fix in Cursor Fix in Web

}
Loading