Repository navigation
fix(api): map the API's full error-code set to CLI error codes - #661
Conversation
The API returns a stable, machine-readable `code` on every error body, and statusToErrorCode() prefers it over the HTTP status. SERVER_CODE_MAP only knew nine keys, five of which the API never sends, so most codes leaked through as raw strings and a 401 `unauthenticated` no longer triggered the "Not logged in. Run: nansen login" hint. - Key SERVER_CODE_MAP on every code documented at https://docs.nansen.ai/getting-started/error-handling, keeping the old keys as aliases so older responses still map. - Add PLAN_UPGRADE_REQUIRED, GEO_BLOCKED, QUERY_TOO_LARGE, PAYLOAD_TOO_LARGE, METHOD_NOT_ALLOWED and CONFLICT to ErrorCode, with matching status fallbacks for bodies that carry no code. - Retry decisions are unchanged (keyed on HTTP status); tests pin that, along with the 23-code table, the legacy aliases, unknown-code passthrough and the login hint. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pr-reviewer Summary for #75f9249📝 1 finding Review completed. Please address the findings below. Findings by Severity
Review effort: 2/5 (Simple) SummaryThis PR correctly wires the full set of documented API error codes into the CLI. The Findings (1 low)
|
There was a problem hiding this comment.
Auto-approved
This PR was automatically approved because:
- Claude recommends approval
- Claude assessed this as a moderate effort change
- The effort level is within the auto-approval threshold of 2
- No high or critical issues were detected
If you have any concerns, please request a manual review.
There was a problem hiding this comment.
Auto-approved
This PR was automatically approved because:
- Claude recommends approval
- Claude assessed this as a moderate effort change
- The effort level is within the auto-approval threshold of 2
- No high or critical issues were detected
- Review comment contains non-blocking feedback
If you have any concerns, please request a manual review.
|
Addressed the reviewer note: the PR description now documents |
Summary
The API returns a structured error body with a stable, machine-readable
codeon every error, andstatusToErrorCode()prefers that code over the HTTP status. The CLI'sSERVER_CODE_MAPonly knew nine keys, five of which the API never sends, so most real codes leaked through as raw snake_case strings and every consumer keyed onErrorCodesilently missed them. Most visibly, a 401 arrives asunauthenticated(notunauthorized), so theNot logged in. Run: nansen loginhint never fired.After this change the CLI recognises the full set of codes documented on the API's error-handling page, the login hint is back for
unauthenticated, andinsufficient_creditsgets its do-not-retry hint again, whileunknown_fieldretains the API’s field-name guidance.Changes
src/api.jsSERVER_CODE_MAPnow keys on all 23 documented codes and is exported so tests can pin it. The five old keys (unauthorized,payment_required,unsupported_filter,validation_error,invalid_params) stay as aliases so older responses still map.ErrorCodegainsPLAN_UPGRADE_REQUIRED,GEO_BLOCKED,QUERY_TOO_LARGE,PAYLOAD_TOO_LARGE,METHOD_NOT_ALLOWED,CONFLICT— each has a distinct remediation thatINVALID_PARAMSorTIMEOUTwould misstate (e.g.query_too_largeis "narrow the query", not "retry").missing_field→MISSING_PARAM,invalid_address_format→INVALID_ADDRESS,unknown_field→INVALID_PARAMSso the API’s typo/location guidance is preserved without an unrelated token/chain filter hint; the rest →INVALID_PARAMS.query_timeout→TIMEOUT,upstream_unavailable→SERVICE_UNAVAILABLE,internal_error→SERVER_ERROR.code: 405, 408, 409, 413, 451 now map to the matching new codes instead of the generic 4xx default.429/500/502/503/504), so the remap cannot change which responses are retried.src/__tests__/error-codes.test.js(new): table-driven cases for all 23 codes, a divergence check that fails if a documented code is missing from the map (or a stray key appears), legacy-alias fallback, unknown-code passthrough, server code winning over prose, accurateunknown_fieldremediation, structured server-sidemissing_fieldoutput, the 401unauthenticatedlogin hint with and without a configured key, and retry semantics per code (retried on 429/500/503/504, not retried on 403/409/422/451).README.md:PLAN_UPGRADE_REQUIREDandGEO_BLOCKEDrows in the critical error-code table, plus a pointer to the public error-handling page..changeset/server-error-code-map.md: patch.Server
missing_fieldmaps toMISSING_PARAMbut remains a structured JSON error even in an interactive terminal; only local usage banners use the plain-text TTY rendering path.Validation
npm run lint— clean (no output fromeslint .).Live check (read-only, no credits spent): an invalid key against
api.nansen.aireturns HTTP 401 with a plain{"message": ...}body and nocode, which the existing status fallback already handled; theunauthenticatedcode is the documented body shape this change covers.Checklist
npm test)src/schema.jsonupdated if new commands or flags were added — none addedREADME.mdupdated if new top-level commands or categories were added — error-code table extended.changeset/) — only required for user-facing changes (new commands, flags, bug fixes, breaking changes)🤖 Generated with Claude Code