Skip to content

fix: check the HTTP status code for JSON responses - #471

Open
mvanhorn wants to merge 1 commit into
MacPaw:mainfrom
mvanhorn:fix/469-json-response-http-status
Open

mvanhorn wants to merge 1 commit into
MacPaw:mainfrom
mvanhorn:fix/469-json-response-http-status

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

What

All four URLResponseHandler entry points, JSON and raw, with and without an error argument, now take the body from interceptedData. Middleware runs first, a transport error is rethrown unchanged, and throwIfErrorStatus then treats a status of 400 or above as a decoded APIErrorResponse or GeminiAPIErrorResponse, or as OpenAIError.statusError when the body is neither. The body is returned only after that check, and a missing body throws OpenAIError.emptyData; JSON decoding still happens next, so a 2xx payload that is an API or Gemini error document still surfaces that error. unwrap is removed, the changelog records the new JSON error behavior, and tests cover completion-handler, async, and Combine calls for an API error body, an HTML body, relaxed partial payloads, a 200 error document, a transport failure, and Gemini error shapes.

JSON calls could turn a failed HTTP response into the wrong outcome. A body that is not an API error, such as an HTML page from a proxy or gateway, reached the caller as a DecodingError on the expected result type, with no status code attached. Under ParsingOptions.relaxed, a status of 400 or above whose body left required fields out could decode into a result filled with defaults and be returned as success. The JSON overloads of URLResponseHandler ran response middleware and then decodeJson, and never called throwIfErrorStatus. That status check existed only on the raw-data overloads. An API error was recognized only when decoding the expected type failed and the JSON decoder fell back to an API error document, which misses an HTML body and never runs when relaxed decoding already accepts the body as the result.

Fixes #469

Why

All four URLResponseHandler entry points, JSON and raw, with and without an error argument, now take the body from interceptedData. Middleware runs first, a transport error is rethrown unchanged, and throwIfErrorStatus then treats a status of 400 or above as a decoded APIErrorResponse or GeminiAPIErrorResponse, or as OpenAIError.statusError when the body is neither. The body is returned only after that check, and a missing body throws OpenAIError.emptyData; JSON decoding still happens next, so a 2xx payload that is an API or Gemini error document still surfaces that error. unwrap is removed, the changelog records the new JSON error behavior, and tests cover completion-handler, async, and Combine calls for an API error body, an HTML body, relaxed partial payloads, a 200 error document, a transport failure, and Gemini error shapes.

Affected Areas

Scoped to the files listed above; no other caller or consumer changes.

All four URLResponseHandler entry points, JSON and raw, with and without
an error argument, now take the body from interceptedData. Middleware
runs first, a transport error is rethrown unchanged, and
throwIfErrorStatus then treats a status of 400 or above as a decoded
APIErrorResponse or GeminiAPIErrorResponse, or as
OpenAIError.statusError when the body is neither. The body is returned
only after that check, and a missing body throws OpenAIError.emptyData;
JSON decoding still happens next, so a 2xx payload that is an API or
Gemini error document still surfaces that error. unwrap is removed, the
changelog records the new JSON error behavior, and tests cover
completion-handler, async, and Combine calls for an API error body, an
HTML body, relaxed partial payloads, a 200 error document, a transport
failure, and Gemini error shapes.

Fixes MacPaw#469
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.

Check the HTTP status code for JSON responses

1 participant