Repository navigation
Feat: Add HTTPResponseError for HTTP failures, including streaming - #491
Open
luis-silva-ms wants to merge 2 commits into
Open
luis-silva-ms wants to merge 2 commits into
luis-silva-ms wants to merge 2 commits into
Conversation
HTTP status failures (>= 400) from JSON, raw-data and streaming requests now throw a single HTTPResponseError carrying the status code, the HTTP response, the raw body (truncated for streams), the decoded API error when available and any underlying transport error. Streaming failures now run response middleware, skip SSE middleware for error bodies, cap the collected error body, and rethrow cancellation unchanged.
luis-silva-ms
marked this pull request as ready for review
November 11, 2026 17:00
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.
TL;DR: Add HTTPResponseError that keeps the status code and body of a (>=400) response so custom errors are not lost.
Why
When a request fails at the HTTP level, callers often can't read the error:
{"error":{"code":"…","message":"…"}}withouttype, or a flat{"code":"…","message":"…"}.APIErrorrequirestype, so decoding fails. The caller then getsOpenAIError.statusErrorwith only the status code, and thecodeandmessageare lost. Non-JSON bodies (HTML, plain text) are lost the same way.What
HTTP status failures (status >= 400) now throw a single public error type,
HTTPResponseError, for JSON, raw-data and streaming requests.HTTPResponseErrorexposes:statusCodeandresponse(HTTPURLResponse)body: the raw error body (Data), kept even when the SDK can't decode it: for example a gateway's custom error JSON, or a non-JSON bodyapiError: the decodedAPIErrorResponse/GeminiAPIErrorResponsewhen the body is oneunderlyingError: a transport error that arrived with the failing responseStreaming (
StreamingSession) changes:CancellationError/URLError.cancelled) is rethrown as is, not wrapped.There is no source break:
swift package diagnose-api-breaking-changes 0.6.0reports no breaking changes. Only a public type is added.It is a runtime behaviour change. Code that catches
APIErrorResponse,GeminiAPIErrorResponseorOpenAIError.statusErrorfor HTTP failures will silently stop matching. It should catchHTTPResponseErrorand readapiError/statusCodeinstead. Errors sent inside a successful (2xx) stream keep their existing types.Affected Areas
Sources/OpenAI/Public/Errors/HTTPResponseError.swift: new public typeSources/OpenAI/Private/URLResponseHandler.swift: non-streaming error pathSources/OpenAI/Private/Streaming/StreamingSession.swift: streaming error pathURLResponseHandlerTests; extendedStreamingSessionErrorHandlingTestsandMockMiddleware.JSONResponseStatusTests,FilesEndpointTestsandOpenAITestsupdated to expectHTTPResponseError.ResponsesStorestatus hints)Validation
swift build: ✅ passedswift test: ✅ passed (277 XCTest, 0 failures; 35 Swift Testing tests passed)xcodebuild -project Demo/Demo.xcodeproj -scheme Demo -destination "generic/platform=iOS Simulator" build: ✅ BUILD SUCCEEDEDswift package diagnose-api-breaking-changes 0.6.0: ✅ No breaking changes detected in OpenAIHTTPURLResponse/URLRequestimportFoundationNetworkingunder#if canImport(FoundationNetworking).