Skip to content

Add a callback for client response decoding errors #912

Description

@mikolaj92

Problem

Generated client calls currently wrap response decoding failures in ClientError, which gives useful context like operation ID, request, response, response body, cause, and the underlying decoding error.

However, adopters do not have a central place to observe those decoding failures.

In production, this makes it hard to report response decoding problems consistently without wrapping every generated client call manually.

do {
    let output = try await client.getUser(.init(path: .init(id: id)))
    // use output
} catch {
    errorReporter.record(error)
    throw error
}

This works, but it is easy to miss call sites and it repeats the same reporting code across the app.

Middleware is useful for HTTP-level logging, but it observes the request/response around the transport call. The decoding failure happens later, when the runtime decodes the response body into the generated output type.

Proposed direction

Add a small callback on Configuration for response decoding failures:

public var clientResponseDecodingErrorHandler: (@Sendable (ClientError) -> Void)?

The callback would be called when response decoding fails, after the failure has been wrapped in ClientError.

The callback receives ClientError rather than the raw decoding error because the wrapped error includes operation and HTTP context. The raw decoding error remains available as ClientError.underlyingError.

The same ClientError would still be thrown to the caller.

Prior work

This builds on the discussion in:

Those PRs identified the same general production problem. This issue proposes a simpler model focused only on response decoding failures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions