Skip to content

anthropic: caller exception inside a with_streaming_response block records a successful span #389

Description

@lmolkova

What happens

An exception raised by the caller inside a with_streaming_response block finalizes the span as a success — no error.type, status UNSET:

with client.messages.with_streaming_response.create(..., stream=True) as raw:
    for _ in raw.parse():
        raise ValueError("boom")

messages.create(stream=True) and messages.stream(...) both record error.type for the equivalent caller-side error, so the raw-response path is inconsistent with the rest of the package.

Why

The SDK's ResponseContextManager.__exit__ (and AsyncResponseContextManager.__aexit__) receives the caller's exception and discards it, calling response.close() with no exc_info:

def __exit__(self, exc_type, exc, exc_tb) -> None:
    if self.__response is not None:
        self.__response.close()

The instrumentation wraps the response, not the context manager, so it only ever observes a plain close and cannot distinguish success from failure.

Fix direction

Instrument MessagesWithStreamingResponse.create / AsyncMessagesWithStreamingResponse.create and wrap the returned ResponseContextManager, so its __exit__ sees the real exc_info and can fail the invocation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status
    New issues

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions