Skip to content

Accept pre-parsed JSON body in HttpError.from()#1

Closed
freshlogic wants to merge 2 commits into
mainfrom
fromjson
Closed

Accept pre-parsed JSON body in HttpError.from()#1
freshlogic wants to merge 2 commits into
mainfrom
fromjson

Conversation

@freshlogic

@freshlogic freshlogic commented May 12, 2026

Copy link
Copy Markdown
Member

Summary

`HttpError.from(response)` now accepts an optional second argument: an already-parsed JSON body. When supplied, the factory skips the body read and sets `err.json` and `err.text` from the supplied value.

This covers the common case of an application-level error envelope on an otherwise-ok response — GraphQL servers (always 200 OK with `data.errors[]`) and some REST APIs (FedEx Rate, etc.) that return 200 with an `errors[]` envelope. The caller has already called `response.json()` to inspect the body and now wants to throw with the body attached.

Before:

```js
const err = new HttpError(res);
err.json = json;
err.text = JSON.stringify(json);
err.message = json.errors.map(e => e.message).join('; ');
throw err;
```

After:

```js
const err = await HttpError.from(res, json);
err.message = json.errors.map(e => e.message).join('; ');
throw err;
```

Design notes

  • One factory instead of two — caller doesn't have to choose between `from` and `fromJson`
  • Signature stays async (callers were awaiting anyway); no IO when `json` is provided
  • No opinion on message format — errors-envelope shapes vary (GraphQL uses `message`; FedEx uses `code`+`message`; JSON:API uses `detail`+`title`+`source`). Callers override `.message` after construction.
  • Fully backward compatible — single-arg `from(response)` is unchanged

Test plan

  • `from(response, json)` sets `.json`, `.text`, `.cause`, and `.name` correctly
  • Caller can override `.message` after construction
  • All existing single-arg `from()` tests still pass

🤖 Generated with Claude Code

GraphQL servers always return 200 OK with errors carried in data.errors[],
and some REST APIs (FedEx, etc.) do the same — a 2xx response carries an
application-level errors envelope. Callers that need to throw on those
already have the parsed body in hand from response.json() and just want to
attach it to an HttpError.

HttpError.fromJson(response, json) is a synchronous factory that sets
err.json = json and err.text = JSON.stringify(json), leaving the message
at the default "${status} ${statusText}" so callers can override it with
whatever aggregated form makes sense for their API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coveralls

coveralls commented May 12, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 25706064232

Coverage remained the same at 100.0%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 12 of 12 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 46
Covered Lines: 46
Line Coverage: 100.0%
Relevant Branches: 8
Covered Branches: 8
Branch Coverage: 100.0%
Branches in Coverage %: Yes
Coverage Strength: 2.57 hits per line

💛 - Coveralls

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@freshlogic freshlogic changed the title Add HttpError.fromJson() for 2xx responses with error envelopes Accept pre-parsed JSON body in HttpError.from() May 12, 2026
@freshlogic

Copy link
Copy Markdown
Member Author

Closing — went with the clone-before-consume pattern on the caller side instead, no http-error change needed.

@freshlogic freshlogic closed this May 12, 2026
@freshlogic freshlogic deleted the fromjson branch May 12, 2026 00:43
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.

2 participants