Skip to content

fix(widget): expose transaction signing errors#537

Merged
Philippoes merged 1 commit into
mainfrom
fix/expose-tx-signing-error
Jun 16, 2026
Merged

fix(widget): expose transaction signing errors#537
Philippoes merged 1 commit into
mainfrom
fix/expose-tx-signing-error

Conversation

@petar-omni

@petar-omni petar-omni commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Enhanced error handling to display custom messages from external wallet providers when transaction signing or approval fails.
  • Bug Fixes

    • Improved error message clarity with updated generic error text.
  • Style

    • Updated error banner styling to use consistent theme tokens for border radius and background colors.
  • preserve custom external provider signing errors separately from generic wallet errors
  • show custom signing errors in a dedicated error banner on transaction steps
  • keep transaction step error labels generic and add coverage for custom provider errors

@changeset-bot

changeset-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: dbebea0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an ExternalProviderError class and toExternalProviderError helper to centralize external provider error conversion. The custom message is threaded through SendTransactionError and SignError, propagated via the steps state machine into useSteps, and rendered as a conditional error banner in StepsPage. Banner border radii are tokenized and an errorBoxBackground color token is added.

Changes

Custom external provider error propagation

Layer / File(s) Summary
Error class contracts and helper
src/domain/types/external-providers.ts, src/providers/sk-wallet/errors.ts, src/pages/steps/hooks/errors.ts
ExternalProviderError class with customMessage and cause is introduced alongside toExternalProviderError. SendTransactionError and SignError constructors are extended to accept and store customMessage.
Provider-level error conversion
src/domain/types/external-providers.ts, src/providers/sk-wallet/index.tsx
sendTransaction and signMessage in both provider files wrap failures via toExternalProviderError or preserve ExternalProviderError instances and pass customMessage into SendTransactionError.
Steps state machine and hook propagation
src/pages/steps/hooks/use-steps-machine.hook.ts, src/pages/steps/hooks/use-steps.hook.ts
TxMeta.signError union widens to include SignError; mapLeft populates customMessage from ExternalProviderError; useSteps exposes memoized customSignErrorMessage.
StepsPage banner rendering and styling
src/pages/steps/pages/common.page.tsx, src/pages/steps/pages/styles.css.ts, src/pages/steps/pages/tx-state.tsx, src/styles/tokens/colors/contract.ts, src/styles/tokens/colors/values.ts, src/translation/English/translations.json, src/translation/French/translations.json
Conditional custom sign error banner added to StepsPage; banner borderRadius uses theme token; errorBoxBackground color token added; tx-state error text switches to unconditional translation key; translations simplified to generic message; retry button variant respects dashboardVariant.
sk-wallet error propagation test
tests/use-cases/sk-wallet.test.tsx
New test verifies SendTransactionError with correct message and customMessage when external provider rejects a Solana transaction with a structured error payload.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hops through the error maze with care,
Wrapping custom messages, clean and fair.
From provider depths to banner bright,
ExternalProviderError shines in light.
No more hardcoded "20px" in sight—
The rabbit tokenized everything right! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description lacks the required template structure (Added/Changed sections) and provides only high-level bullet points without comprehensive details. Restructure the description using the template format with 'Added' and 'Changed' sections that detail all modifications made to error handling, UI components, and type definitions.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: exposing transaction signing errors for better error handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/expose-tx-signing-error

Comment @coderabbitai help to get the list of available commands and usage tips.

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-537.df4xyoi0xyeak.amplifyapp.com

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-537.d2ribjy8evqo6h.amplifyapp.com

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/widget/src/pages/steps/hooks/use-steps.hook.ts (1)

171-183: Remove useMemo for customSignErrorMessage and compute it inline.

The memoization at lines 171–183 wraps a derived primitive value (string or null) that is used only for its value in conditional rendering and text display. With React Compiler enabled, memoization for render-performance optimization of primitive values should be avoided; use plain computation instead.

Suggested change
-  const customSignErrorMessage = useMemo(() => {
-    const error = machineState.context.currentTxMeta
-      .chainNullable((currentTxMeta) => {
-        return machineState.context.txStates[currentTxMeta.idx]?.meta.signError;
-      })
-      .extractNullable();
-
-    if (!error || !("customMessage" in error)) return null;
-
-    return typeof error.customMessage === "string" && error.customMessage
-      ? error.customMessage
-      : null;
-  }, [machineState.context.currentTxMeta, machineState.context.txStates]);
+  const error = machineState.context.currentTxMeta
+    .chainNullable((currentTxMeta) => {
+      return machineState.context.txStates[currentTxMeta.idx]?.meta.signError;
+    })
+    .extractNullable();
+
+  const customSignErrorMessage =
+    error &&
+    typeof error === "object" &&
+    "customMessage" in error &&
+    typeof error.customMessage === "string" &&
+    error.customMessage
+      ? error.customMessage
+      : null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/widget/src/pages/steps/hooks/use-steps.hook.ts` around lines 171 -
183, The customSignErrorMessage variable is wrapped in a useMemo hook to memoize
a derived primitive value (string or null), which is unnecessary with React
Compiler enabled. Remove the useMemo wrapper entirely and compute the value
inline by moving the logic inside useMemo directly into a const declaration,
eliminating the useMemo call and its dependency array. This allows the primitive
value to be computed on each render without unnecessary memoization overhead.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/widget/src/pages/steps/hooks/use-steps.hook.ts`:
- Around line 171-183: The customSignErrorMessage variable is wrapped in a
useMemo hook to memoize a derived primitive value (string or null), which is
unnecessary with React Compiler enabled. Remove the useMemo wrapper entirely and
compute the value inline by moving the logic inside useMemo directly into a
const declaration, eliminating the useMemo call and its dependency array. This
allows the primitive value to be computed on each render without unnecessary
memoization overhead.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d89cb53c-32f0-41f5-821e-b5a8146919c4

📥 Commits

Reviewing files that changed from the base of the PR and between 44c7384 and dbebea0.

📒 Files selected for processing (14)
  • packages/widget/src/domain/types/external-providers.ts
  • packages/widget/src/pages/steps/hooks/errors.ts
  • packages/widget/src/pages/steps/hooks/use-steps-machine.hook.ts
  • packages/widget/src/pages/steps/hooks/use-steps.hook.ts
  • packages/widget/src/pages/steps/pages/common.page.tsx
  • packages/widget/src/pages/steps/pages/styles.css.ts
  • packages/widget/src/pages/steps/pages/tx-state.tsx
  • packages/widget/src/providers/sk-wallet/errors.ts
  • packages/widget/src/providers/sk-wallet/index.tsx
  • packages/widget/src/styles/tokens/colors/contract.ts
  • packages/widget/src/styles/tokens/colors/values.ts
  • packages/widget/src/translation/English/translations.json
  • packages/widget/src/translation/French/translations.json
  • packages/widget/tests/use-cases/sk-wallet.test.tsx

@raiseerco raiseerco left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

comment

{txState.state === TxStateEnum.SIGN_ERROR ? (
<Text variant={{ type: "danger" }}>
{txState.meta.signError?.message || t("steps.approve_error")}
{t("steps.approve_error")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

could this make non-custom signing errors less actionable for users? those cases now seem to collapse into the generic approve_error message

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@Philippoes Philippoes merged commit 5122351 into main Jun 16, 2026
8 checks passed
@Philippoes Philippoes deleted the fix/expose-tx-signing-error branch June 16, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants