Skip to content

fix: show real error text in Account Hub instead of "[object Object]"#52

Merged
islandbitcoin merged 1 commit into
mainfrom
fix/account-hub-error-object-object
Jul 13, 2026
Merged

fix: show real error text in Account Hub instead of "[object Object]"#52
islandbitcoin merged 1 commit into
mainfrom
fix/account-hub-error-object-object

Conversation

@islandbitcoin

Copy link
Copy Markdown
Contributor

The bug

The Account Hub error dialog shows [object Object] instead of the real reason a mutation failed:

bug

Root cause

Every Flash GraphQL mutation the page calls returns validation failures as an array of { message } objects — e.g. accountUpdateLevel returns errors { message }. All five Account Hub action handlers rendered them with:

message: Array.isArray(result.errors) ? result.errors.join(", ") : result.errors

Array.join calls String() on each element, so [{message: "..."}] becomes "[object Object]". The screenshot is the Change Level action — the mutation returned a real business-logic reason and the UI threw the text away.

The same latent bug was present in all five handlers: Change Level, Lock/Activate, Update Phone, Validate Merchant, Delete Merchant.

The fix

Add a single formatApiErrors() helper that extracts .message from each error object and route all five handlers through it.

  • [{message}] (the bug) → renders the actual message
  • multiple errors → comma-joined messages
  • plain strings / string arrays → unchanged (backward compatible)
  • unexpected object shapes → JSON fallback instead of [object Object]

Verification

  • node --check passes on the file.
  • Exercised the helper against every real error shape; the bug case now renders "Account is already at MERCHANT level" instead of "[object Object]", with no regression on string/array inputs.

Manual test plan (TEST → PROD)

  1. Open Admin Panel → Account Hub, select an account.
  2. Trigger a mutation that the Flash API will reject — easiest is Change Level to a level the account can't move to (or Lock an already-locked account).
  3. Confirm the Error dialog now shows a human-readable reason, not [object Object].

Out of scope (noted, not changed)

The error: callbacks on these same frappe.calls read err?.responseJSON?.exception || err?.message, which doesn't surface the server message when an endpoint returns via the @handle_api_errors decorator (that lands at err.responseJSON.message.error). Genuine 500s currently show the generic "Failed to …" fallback. Happy to follow up separately if wanted.

🤖 Generated with Claude Code

Flash GraphQL mutations return validation failures as an array of
{ message } objects, but every Account Hub action handler rendered them
with `result.errors.join(", ")`, which String()-coerces each object to
"[object Object]". This masked the actual reason on Change Level, Lock/
Activate, Update Phone, Validate Merchant, and Delete Merchant.

Add a formatApiErrors() helper that extracts .message from each error
object and route all five handlers through it. Plain strings and string
arrays are unchanged; unexpected object shapes fall back to JSON rather
than "[object Object]".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@islandbitcoin
islandbitcoin merged commit a804907 into main Jul 13, 2026
1 check passed
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.

1 participant