Skip to content

feat(frontend): replace raw GenVM JSON errors with plain-English messages#1627

Open
0x-normal wants to merge 3 commits into
genlayerlabs:mainfrom
0x-normal:feat/1609-friendly-genvm-errors
Open

feat(frontend): replace raw GenVM JSON errors with plain-English messages#1627
0x-normal wants to merge 3 commits into
genlayerlabs:mainfrom
0x-normal:feat/1609-friendly-genvm-errors

Conversation

@0x-normal

@0x-normal 0x-normal commented May 11, 2026

Copy link
Copy Markdown

Closes #1609.

Summary

When a contract failed to load or deploy in Studio, the user was shown the raw GenVM result wrapped in a Python repr() — a wall of genvm_log JSON with the only useful signal ("message": "invalid_contract absent_runner_comment") buried inside. New developers had no path forward without asking on Discord.

This PR intercepts the error in the Studio frontend, maps known GenVM codes to plain-English { title, explanation, fix } triples, and collapses the raw payload behind a "Show technical details" toggle with a copy-to-clipboard button for bug reports.

What changed

  • frontend/src/utils/genvmErrors.ts — defensive parser. Extracts the inner GenVM message from JSON, Python repr() output, and bare strings. Maps every VmError code from backend/node/genvm/origin/public_abi.py plus the invalid_contract absent_runner_comment special case. Unknown codes fall back to a generic friendly message; raw is always preserved.
  • frontend/src/components/Simulator/FriendlyError.vue — red alert with title, explanation, optional fix code block, and a collapsed <details> "Show technical details" panel containing the raw payload + CopyTextButton.
  • Wired FriendlyError into the 3 call sites that previously surfaced raw errors:
    • ConstructorParameters.vue (was a generic "Could not load contract schema." with no detail at all)
    • ContractReadMethods.vue (rendered raw error.message)
    • ContractWriteMethods.vue (rendered raw error.message)
  • 21 vitest unit tests covering extraction (clean JSON, Python repr, bare regex), every recognized code, mapping precedence (absent_runner_comment before generic invalid_contract), the unknown-code fallback, and input normalization (Error / object / string / null).

Acceptance criteria (from #1609)

  • Studio intercepts schema/deploy errors before rendering
  • Known error codes render plain-English title + explanation + fix
  • Raw GenVM JSON is collapsed behind "Show technical details"
  • Unknown codes fall back to a generic friendly message
  • Copy-to-clipboard button on the raw error

Verification

  • npx vitest run test/unit/utils/genvmErrors.test.ts — 21/21 pass
  • npx vitest run (full suite, after node scripts/contract-examples.js) — 31 files, 108/108 pass
  • npx vue-tsc --noEmit — clean

Notes for reviewers

The wording for timeout / OOM / validator_disagrees / version_too_big / exit_code is my best inference from the VmError enum and is easy to tweak in review — happy to adjust to your preferred phrasing or to add more codes if I missed any.

Summary by CodeRabbit

  • New Features

    • Unified, user-friendly error UI across the contract simulator with clear titles, explanations, suggested fixes, and a collapsible technical-details view with copyable raw error text.
    • New error-parsing logic to translate raw runtime/RPC errors into readable messages for users.
  • Tests

    • Added unit tests covering extraction and parsing of various runtime/RPC error formats and mappings.

Review Change Stack

…ages

Closes genlayerlabs#1609.

When a contract failed to load or deploy in Studio, the user was shown
the raw GenVM result wrapped in a Python repr() — a wall of `genvm_log`
JSON with the only useful signal (`"message": "invalid_contract
absent_runner_comment"`) buried inside. New developers had no path
forward without asking on Discord.

This change introduces:

- `frontend/src/utils/genvmErrors.ts` — defensive parser that extracts
  the inner GenVM `message` from JSON, Python repr() and bare-string
  payloads, then maps known codes (the full `VmError` set from
  `backend/node/genvm/origin/public_abi.py`, plus the
  `invalid_contract absent_runner_comment` special case) to a
  `{ title, explanation, fix? }` triple. Unknown codes fall back to a
  generic friendly message; the original payload is always preserved on
  `raw` for bug reports.

- `frontend/src/components/Simulator/FriendlyError.vue` — renders the
  parsed result as a red alert with title + explanation + optional fix
  snippet, plus a collapsed `<details>` "Show technical details" panel
  that contains the raw payload and a copy-to-clipboard button (built
  on the existing `CopyTextButton`).

- Wires `FriendlyError` into the three call sites that previously
  surfaced raw errors:
    - `ConstructorParameters.vue` (was a generic
      "Could not load contract schema." with no details at all)
    - `ContractReadMethods.vue` (rendered raw `error.message`)
    - `ContractWriteMethods.vue` (rendered raw `error.message`)

- 21 vitest unit tests covering extraction (clean JSON, Python repr,
  bare regex), every recognized code, mapping precedence
  (`absent_runner_comment` before generic `invalid_contract`), the
  unknown-code fallback, and input normalization (Error / object /
  string / null).

Acceptance criteria from genlayerlabs#1609:

- [x] Studio intercepts schema/deploy errors before rendering
- [x] Known error codes render plain-English title + explanation + fix
- [x] Raw GenVM JSON is collapsed behind "Show technical details"
- [x] Unknown codes fall back to a generic friendly message
- [x] Copy-to-clipboard button on the raw error
@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3c00a09e-4499-4446-a089-4486d66dcc59

📥 Commits

Reviewing files that changed from the base of the PR and between 610baaa and af55537.

📒 Files selected for processing (2)
  • frontend/src/utils/genvmErrors.ts
  • frontend/test/unit/utils/genvmErrors.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/utils/genvmErrors.ts
  • frontend/test/unit/utils/genvmErrors.test.ts

📝 Walkthrough

Walkthrough

This PR centralizes GenVM error parsing, adds a FriendlyError Vue component, integrates it into three simulator pages, and adds unit tests for extraction and mappings.

Changes

GenVM Error Handling & Display

Layer / File(s) Summary
Error Data Model & Parsing Utility
frontend/src/utils/genvmErrors.ts
Defines FriendlyError interface, GENERIC_FALLBACK, extractGenVMMessage, findMessage, ordered MAPPINGS, parseGenVMError, and stringifyError to normalize and map raw GenVM/RPC errors into UI-ready objects.
Error Display Component
frontend/src/components/Simulator/FriendlyError.vue
New Vue SFC accepting error: unknown, computing friendly = parseGenVMError(error), and rendering title, explanation, optional fix block, and collapsible technical details with copy-to-clipboard.
Simulator Page Integration
frontend/src/components/Simulator/ConstructorParameters.vue, frontend/src/components/Simulator/ContractReadMethods.vue, frontend/src/components/Simulator/ContractWriteMethods.vue
Each component imports FriendlyError and replaces inline Alert/error markup with <FriendlyError v-else-if="isError" :error="error" />, adjusting query destructuring where needed.
Unit Tests
frontend/test/unit/utils/genvmErrors.test.ts
Vitest coverage for extractGenVMMessage (JSON, repr-style, regex fallback), parseGenVMError mappings (known codes, precedence, unknown fallbacks), and input normalization (Error, object, null/undefined).

Sequence Diagram

sequenceDiagram
  participant SimulatorPage as Simulator Page\n(Constructor/Read/Write)
  participant Query as Query Result\n(error object)
  participant FriendlyError as FriendlyError\nComponent
  participant parseGenVMError as parseGenVMError\nUtility
  participant MAPPINGS as Error Code\nMappings
  participant UI as Rendered UI

  SimulatorPage->>Query: Receives error from query
  SimulatorPage->>FriendlyError: Pass error prop
  FriendlyError->>parseGenVMError: Parse error
  parseGenVMError->>parseGenVMError: Extract message/code
  parseGenVMError->>MAPPINGS: Look up code/pattern
  MAPPINGS-->>parseGenVMError: Return friendly payload
  parseGenVMError-->>FriendlyError: Return FriendlyError object
  FriendlyError->>UI: Render title, explanation, optional fix, technical details
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • cristiam86

Poem

🐰 A rabbit hops to clear the view,
Raw JSON scared the devs — boo-hoo.
Friendly words now light the way,
Fix hints land where errors lay.
Copy the details, file the bug — huzzah!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: replacing raw GenVM JSON errors with user-friendly plain-English messages throughout the frontend.
Description check ✅ Passed The PR description is comprehensive, covering what changed, why, testing performed, and includes verification results. It follows the repository template structure with clear sections.
Linked Issues check ✅ Passed All acceptance criteria from #1609 are met: errors are intercepted, known codes map to friendly messages, raw JSON is hidden behind a toggle, unknown codes fall back gracefully, and copy-to-clipboard is implemented.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #1609: new error parsing utility, FriendlyError component, and integration into three error rendering locations. No unrelated modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
frontend/src/components/Simulator/FriendlyError.vue (1)

1-1: ⚡ Quick win

Align the SFC filename with the repo’s Vue naming convention.

This new file is PascalCase (FriendlyError.vue), but the frontend guideline asks for kebab-case Vue filenames. Consider renaming to friendly-error.vue and updating imports.

As per coding guidelines, "frontend/src/**/*.{ts,tsx,vue}: ... prefer PascalCase components, camelCase stores and utilities, and kebab-case Vue file names".

🤖 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 `@frontend/src/components/Simulator/FriendlyError.vue` at line 1, Rename the
Vue Single File Component from FriendlyError.vue to friendly-error.vue and
update all imports/usages to the kebab-case filename (e.g., change import paths
referencing "FriendlyError.vue" to "friendly-error.vue"); search for references
to FriendlyError (component imports, router lazy-loads, or test files) and
update those import paths so they match the new filename, preserving any <script
setup> component name or export unchanged.
🤖 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.

Inline comments:
In `@frontend/src/utils/genvmErrors.ts`:
- Around line 209-212: The fallback branch recomputes code with
extractGenVMMessage and loses the normalized/validated code computed earlier in
parseGenVMError; update the fallback return to reuse the already-normalized
variable (the value produced by parseGenVMError's normalization logic) instead
of calling extractGenVMMessage again so that bare-string inputs and unknown
codes are preserved; locate symbols parseGenVMError, extractGenVMMessage and
GENERIC_FALLBACK and replace the fallback object’s code field to reference the
normalized code variable used earlier.

---

Nitpick comments:
In `@frontend/src/components/Simulator/FriendlyError.vue`:
- Line 1: Rename the Vue Single File Component from FriendlyError.vue to
friendly-error.vue and update all imports/usages to the kebab-case filename
(e.g., change import paths referencing "FriendlyError.vue" to
"friendly-error.vue"); search for references to FriendlyError (component
imports, router lazy-loads, or test files) and update those import paths so they
match the new filename, preserving any <script setup> component name or export
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f78e3f46-fd2a-4835-860f-48232f1e7d43

📥 Commits

Reviewing files that changed from the base of the PR and between 6736a15 and 610baaa.

📒 Files selected for processing (6)
  • frontend/src/components/Simulator/ConstructorParameters.vue
  • frontend/src/components/Simulator/ContractReadMethods.vue
  • frontend/src/components/Simulator/ContractWriteMethods.vue
  • frontend/src/components/Simulator/FriendlyError.vue
  • frontend/src/utils/genvmErrors.ts
  • frontend/test/unit/utils/genvmErrors.test.ts

Comment thread frontend/src/utils/genvmErrors.ts
0x-normal and others added 2 commits May 11, 2026 22:37
Per CodeRabbit review: the generic fallback path previously re-ran extractGenVMMessage and dropped the bare-string code, so unrecognized bare inputs came back with code: undefined while recognized bare inputs (e.g. 'OOM') came back with code: 'OOM'. Compute the normalized code once and reuse it in both paths so the field is consistent for any input shape. Adds two regression tests.
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.

[UX] Replace raw GenVM JSON errors in Studio with plain-English messages

1 participant