Skip to content

fix(pairing): show the server's error message instead of the raw AxiosError#38

Open
ClaydeCode wants to merge 2 commits into
mainfrom
fix/clayde/pairing-error-message
Open

fix(pairing): show the server's error message instead of the raw AxiosError#38
ClaydeCode wants to merge 2 commits into
mainfrom
fix/clayde/pairing-error-message

Conversation

@ClaydeCode

Copy link
Copy Markdown
Contributor

Frontend half of FreeshardBase/freeshard#156. Pairs with FreeshardBase/freeshard#164, which makes the backend send the reason.

Problem

Pair.vue and Terminals.vue bound the caught axios error object straight into the template, so a failed pairing rendered AxiosError: Received HTTP status 401 — the exact symptom Stefan reported.

Change

Both views now render through the existing errorMessage filter ({{ err | errorMessage }}), which already extracts response.data.detail and is used the same way in Apps.vue and AppStoreEntry.vue. The issue spec suggested inlining response?.response?.data?.detail; reusing the filter avoids a third pattern for the same job, and optional chaining is not used anywhere in this codebase (Vue 2 templates cannot compile it).

That filter dereferenced error.response.data unguarded, so it threw a TypeError on any error without a response — exactly the network-failure case where the user most needs a message. It is now guarded and falls back to the axios message. This also fixes the same latent crash for the two pre-existing call sites.

The filter moved to src/lib/errors.js so it can be unit-tested: main.js mounts the app on import, so nothing defined there is reachable from a test. lib/ + a matching tests/unit spec is the existing pattern (see lib/pricing.js).

Verification

Test Suites: 4 passed, 4 total
Tests:       24 passed, 24 total

vue-cli-service lint → no errors. vue-cli-service build → build complete, which is what proves the template filter compiles.

Note: build needs NODE_OPTIONS=--openssl-legacy-provider on Node 20 (webpack 4 / OpenSSL 3). Pre-existing on main, unrelated to this change, left alone.

I did not drive the real browser end-to-end. The chain is covered in pieces: the backend returns the detail (tested in freeshard#164), the filter extracts it (tested here), and the templates apply it (build compiles).

Recommended reading order

  1. src/lib/errors.js — extracted, now null-safe
  2. src/main.js — filter registration
  3. src/views/Pair.vue, src/views/Terminals.vue — the two render sites
  4. tests/unit/errors.spec.js
  5. agents.md

Docs

agents.md gained the src/lib/ entry (missing entirely, though lib/pricing.js predates this change) and the error-rendering convention.

🤖 Generated with Claude Code

…sError

Pair.vue and Terminals.vue assigned the caught axios error object straight
to the message rendered in the template, so a failed pairing showed
"AxiosError: Received HTTP status 401" instead of what went wrong. The
backend now sends a specific reason in the response body's detail field
(FreeshardBase/freeshard#156); this renders it.

Both views now pipe the error through the existing errorMessage filter,
which already extracts response.data.detail and is used the same way in
Apps.vue and AppStoreEntry.vue.

That filter dereferenced error.response.data unguarded, so it threw a
TypeError on any error without a response -- exactly the network-failure
case where the user most needs a message. Guard the lookup and fall back to
the axios message. This also fixes the same latent crash for the two
existing call sites.

Move the filter to lib/errors.js so it can be unit-tested: main.js mounts
the app on import, so nothing defined there is reachable from a test. lib/
with a matching tests/unit spec is the existing pattern (see lib/pricing.js).
src/lib was missing from the project structure entirely although
lib/pricing.js predates this change. Record it along with the rule that
caught errors are rendered through the errorMessage filter, which is the
convention that keeps raw AxiosError text out of the UI.
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