fix(api): surface server error messages instead of a bare ✖ HTTP 400 - #10
Merged
Conversation
Every non-2xx used to render as a bare `✖ HTTP 400`, which cost a full
diagnostic round when `variants add` was broken. The client now reads the
error body once and derives a detail from `message` (string, or a string
array joined with `; `), then `error`, then a short printable non-JSON
body — rendering `✖ HTTP 400 — <detail>` on the existing error path, so
every command benefits without per-command changes.
Bodies with nothing usable — today's production `{statusCode, timestamp,
path}`, an empty body, a stripped body, an HTML error page, or the
intentionally bare 500 — degrade to exactly the previous `✖ HTTP <status>`
output. `--json` behaviour is unchanged: errors go to stderr and stdout
stays empty, so machine output stays machine output.
Bumps the version to 0.3.1. The release itself waits until travel-plans
#127 is merged and deployed, so the improvement is real when it ships.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsdP2hvt4XQhYxkdNREXUq
… error messages) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AsdP2hvt4XQhYxkdNREXUq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Every non-2xx from the MNA API currently renders as a bare
✖ HTTP 400— that blindness cost a full diagnostic round whenvariants addwas broken. This makes the CLI print whatever the server actually said, defensively.One implementation, in the
openapi-fetchresponse middleware (src/api/client.ts), so every command benefits — no per-command patching. On a non-2xx the body is read once and a detail is derived in order:message— string, or a string array (NestJS validation convention) joined with;errorWith a detail:
✖ HTTP 400 — location.coordinates must be { lat, lng }.Without one:
✖ HTTP 400— byte-for-byte today's output.Degradation
Bodies with nothing usable in them fall back to the bare status line: today's production
{statusCode, timestamp, path}, an empty body, a body stripped by a proxy, an HTML error page, and the intentionally bare 500. Noundefinedever reaches the terminal.--jsonUnchanged and verified end-to-end against a stub server: errors go to stderr via
reportAndExit, stdout stays completely empty on failure. Machine output stays machine output.Tests
src/api/client.test.tsgains cases for message-as-string, message-as-array,errorfallback, short non-JSON body, long/unprintable non-JSON body, empty body (reproduces today's exact output), message-less{statusCode, timestamp, path}body, and a bare 500.Release gating
Version bumped to 0.3.1, but not tagged and not published. The release waits until travel-plans #127 — the server-side fix that stops the global exception filter from dropping
HttpExceptionpayloads — is merged and deployed, so the improvement is real when it ships.OpenAPI snapshot: deferred
#127 also adds flat
address/latitude/longitudeto the v1 event location DTO. Checked the live spec athttps://api.mynextadventure.cloud/v1/openapi.jsonwhile preparing this:EventLocationV1Dtostill has onlygooglePlaceId/name/formattedAddress/coordinates, and the live spec is otherwise byte-identical to the committedopenapi.json. Snapshot left alone; a follow-up commit refreshes it and re-runsbun run codegenafter the deploy.Gates
bun run codegen,bun run typecheck(no diagnostics),bun run lint,bun test(160 pass / 0 fail),bun run build— all clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01AsdP2hvt4XQhYxkdNREXUq