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.
What happens
An exception raised by the caller inside a
with_streaming_responseblock finalizes the span as a success — noerror.type, statusUNSET:messages.create(stream=True)andmessages.stream(...)both recorderror.typefor the equivalent caller-side error, so the raw-response path is inconsistent with the rest of the package.Why
The SDK's
ResponseContextManager.__exit__(andAsyncResponseContextManager.__aexit__) receives the caller's exception and discards it, callingresponse.close()with noexc_info: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.createand wrap the returnedResponseContextManager, so its__exit__sees the realexc_infoand can fail the invocation.