fix(errors): keep lower-snake fail-envelope codes in error.code (#117) - #120
Merged
Merged
Conversation
#114 read `data.error` as a machine code only when it was upper-snake. The API also sends lower-snake codes in the fail envelope (`invalid_code` from api_validations.rb; `invalid_request`, `no_price_data`, `commodity_discontinued`, `commodity_unavailable` from prices_controller.rb), each with its sentence in `data.message`, so the code was dropped. A `data.error` is now a code when it is a snake-case token in one case, upper or lower, with at least one underscore. Sentences, bare words and mixed case stay the message. A value containing the configured key is never copied into `code`, which is not redacted. The nested canonical `error` object still takes precedence, and redaction is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ao5paex73xXvuM424Libo
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 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. Comment |
Merged
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.
Closes #117
What was wrong (re-verified 2026-09-14)
MACHINE_CODE = /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/(src/errors.ts, from #114) accepted only upper-snake. Production also sends lower-snake codes in the JSend fail envelope, with the sentence indata.message. Onmainthose came back witherror.code === "HTTP_ERROR"(or the class default), and the machine code was lost.Live bodies captured from
api.oilpriceapi.comwith the test key:dataGET /v1/prices/latest?by_code=NOT_A_REAL_CODE_XYZ{"error":"invalid_code","message":"Code 'NOT_A_REAL_CODE_XYZ' not found. ...", "suggestions":[], ...}GET /v1/prices/latestwith 11BRENT_FUTURES_*codes{"error":"invalid_request","message":"Futures multi-code latest is limited to 10 codes per request. You sent 11 (11 futures, 0 spot).","hint":"..."}GET /v1/prices/latestwith 21 codes{"error":"Too many commodity codes requested (max: 20, requested: 21)"}: a sentence, must stay the messageGET /v1/fuel-surcharge/nope/latest{"error":"Unknown carrier 'nope'. Covered carriers: ..."}: sentenceGET /v1/subscriptions/<unknown uuid>{"error":{"code":"NOT_FOUND",...}}Which tokens the API sends as
data.error(oilpriceapi-apiorigin/main)VALIDATION_ERROR,WATCH_LIMIT,INTERVAL_FLOOR.invalid_code(api_validations.rb:76),no_price_data(prices_controller.rb:536,:856),invalid_request(:689),commodity_discontinued(:865),commodity_unavailable(:875).errorvalues inapp/are'Unauthorized'(top-levelrender json: { error: 'Unauthorized' }in admin/billing/analytics controllers) and'not_available'(top-level, forecasts). Neither is inside{status: "fail", data}, so neither reaches this code path. A bare word likeforbiddentherefore stays the message.Cross-checked against python-sdk #148, which uses the same rule: a snake-case token, all upper or all lower, ASCII alphanumerics joined by
_, starting with a letter.Fix
A code-shaped value that contains the configured API key is never used as
code.codeis not redacted, and the fixture key (fixture_key_not_a_real_credential) is itself lower-snake, so without this guard the new rule would have copied it intoerror.code. It stays the redacted message. Redaction itself is untouched. The nested canonicalerrorobject still wins.TDD evidence
Red: new tests against
origin/main(7fd722b)src/errors.tsOn old code these new negative-control tests already pass, and must keep passing: the live sentence,
forbidden,Unauthorized,Invalid_Code,invalid-code,1st_error,_invalid,invalid_, key-in-value redaction, and nested-object precedence.Green
Baseline on
7fd722bwas 812 passed | 1 skipped.npx tsc --noEmit: 0npm run lint: 0npx tsc --noEmit -p tsconfig.typecheck.json: 0npm run build: 0npm run storefront:check: validated 39 Node public surfacesnpm run check:secrets: 0npm run snippets:check: 0No version bump and no CHANGELOG heading; release-note text is below.
Release note (2.0.0)
data.errorin lower-snake form (invalid_code,invalid_request,no_price_data,commodity_discontinued,commodity_unavailable) is nowerror.code, withdata.messageaserror.message. These errors previously carriedcode: "HTTP_ERROR"(or the class default). Code that branched on"HTTP_ERROR"for these responses should branch on the specific code.No file in common with #112's PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_015ao5paex73xXvuM424Libo