Skip to content

fix(query): align error display with existdb-openapi#71 envelope - #840

Open
joewiz wants to merge 1 commit into
eXist-db:developfrom
joewiz:fix/query-error-envelope-parity
Open

fix(query): align error display with existdb-openapi#71 envelope#840
joewiz wants to merge 1 commit into
eXist-db:developfrom
joewiz:fix/query-error-envelope-parity

Conversation

@joewiz

@joewiz joewiz commented Jun 27, 2026

Copy link
Copy Markdown
Member

[This PR was prompted by Joe, drafted by Claude Code, and reviewed by Joe.]

Summary

Brings eXide's query-error display to parity with eXist-db/existdb-openapi#71's error envelope — the QueryError schema { code, message, line, column, raw } (HTTP 400): a concise human message, with the verbose W3C/Java boilerplate moved to raw and user-relative line/column. eXide's Run path consumes existdb-openapi's /api/query directly (runQueryCursor../existdb-openapi/api/query), so it sees this envelope. The change makes eXide prefer the concise message, keep raw available on hover, and fall back gracefully to the generic { error } shape that current existdb-openapi releases (≤ v0.9.7) still return.

eXide handles exactly these two shapes — QueryError (incoming, eXist-db/existdb-openapi#71) and generic { error } (current release). The intermediate { code, description, module, value } shape that some pre- eXist-db/existdb-openapi#71 dev builds emit was never tagged and won't be (releases go { error }QueryError), so it isn't carried.

Changes

  • runQueryCursor (src/eXide.js): factor a single queryErrorMessage() helper used by both the !response.ok branch and the 200-body guard (eXide#828). It prefers message (QueryError), then error (generic), then raw — so the pill shows the clean cause on either shape.
  • src/error-status-ui.js: the detail panel and the hover-dump render message and expose raw on hover, and fall back to the plain-text formatter for the generic { error } so the panel is never blank. The pure formatters move to module scope (out of init()) so they can be unit-tested; the DOM bootstrap is guarded for that.

Tests

  • test/error-status-ui-test.js (5 tests, node --test): pins the message/raw split and the generic-{ error } fallback against the real envelope samples captured from existdb-openapi. Mutation-verified — reverting the message preference fails the panel test, dropping the raw line fails the dump test, and removing the { error } fallback fails the generic test.
  • query_error_structured_spec.cy.js: a version-robust live case (any envelope surfaces an error pill with the cause), plus a cy.intercept case that stubs the fix(query): user-relative line/column + clean message in /api/query error envelope existdb-openapi#71 envelope to exercise the full client path (queryErrorMessageevalError → structured panel) deterministically, independent of the bed's existdb-openapi version.

Verification note

The node unit tests run green and are mutation-verified. The Cypress specs are written but I was not able to run them against a live bed in this pass: validating the eXist-db/existdb-openapi#71 envelope end-to-end needs a bed carrying both this eXide build and a post- eXist-db/existdb-openapi#71 (whose newer langservice dependency the local pkg bed doesn't satisfy). They will run in CI / against a matching bed.

Background

The eXist-db/existdb-openapi#71 heads-up originally pointed at eXide's own query:execute catch, but that endpoint is unused (the editor calls existdb-openapi directly) and is retired separately. The live error display is the existdb-openapi response path addressed here.

The query error envelope existdb-openapi will return going forward is eXist-db#71's
QueryError schema — { code, message, line, column, raw } (HTTP 400): a
concise human `message`, with the verbose W3C/Java boilerplate moved to
`raw`, and user-relative line/column. Current existdb-openapi releases
(≤ v0.9.7) instead return a generic { error: "..." }. eXide's run path
(runQueryCursor → ../existdb-openapi/api/query) consumes whichever the
deployed version returns, so handle both — and only these two: the
{ code, description, module, value } shape some pre-eXist-db#71 dev builds emit was
never tagged and won't be (releases go { error } → QueryError), so it isn't
carried.

- runQueryCursor: factor a single queryErrorMessage() helper used by both
  the !response.ok branch and the 200-body guard (eXide#828). It prefers
  `message` (QueryError), then `error` (generic), then `raw`.
- error-status-ui.js: the panel and hover dump render `message` and expose
  `raw`, and fall back to the plain-text formatter for the generic { error }
  so the detail panel is never blank. The pure formatters move to module
  scope (out of init) so they can be unit-tested.

Tests:
- test/error-status-ui-test.js (5, node --test): pins the message/raw split
  and the generic-{error} fallback against the real envelope samples;
  mutation-verified.
- query_error_structured_spec.cy.js: a version-robust live case (any
  envelope surfaces an error pill with the cause) plus a cy.intercept case
  that stubs the eXist-db#71 envelope to verify the structured panel + message/raw
  split deterministically.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbvYwhBSNMEVmqmZozZ4KS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants