Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ async def _awrap(
if span.is_recording():
span.set_status(Status(StatusCode.ERROR, str(e)))
span.record_exception(e)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The outer start_as_current_span(...) context manager already records any exception that escapes this block (its default is record_exception=True), so this explicit call still creates duplicate exception telemetry even though the duplicate end() is gone. I reproduced this on 9c303fd: changing the new test to assert len(exception_events) == 1 fails with 2 == 1.

Please give one layer sole ownership of exception recording—e.g. remove this manual try/except and let the context manager set ERROR/record the exception, or disable its automatic exception handling—and make the regression assert exact cardinality. With the manual handler removed, the strengthened test plus test_cohere_v2_rerank_legacy_async and test_cohere_chat_legacy_async all pass locally.

span.end()
raise

set_span_response_attributes(span, response)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import logging

import cohere
import pytest
from opentelemetry.instrumentation.cohere import CohereInstrumentor
from opentelemetry.trace import StatusCode


@pytest.mark.asyncio
async def test_async_cohere_exception_records_error_once(
caplog, monkeypatch, span_exporter, tracer_provider
):
async def failing_chat(self, *args, **kwargs):
raise RuntimeError("cohere async failure")

monkeypatch.setattr(cohere.AsyncClient, "chat", failing_chat)
instrumentor = CohereInstrumentor()
instrumentor.instrument(tracer_provider=tracer_provider)

try:
with caplog.at_level(logging.WARNING, logger="opentelemetry.sdk.trace"):
with pytest.raises(RuntimeError, match="cohere async failure"):
await cohere.AsyncClient("test_api_key").chat(
model="command", message="Tell me a joke, pirate style"
)
finally:
instrumentor.uninstrument()

spans = span_exporter.get_finished_spans()
assert len(spans) == 1
span = spans[0]
assert span.name == "cohere.chat"
assert span.status.status_code == StatusCode.ERROR
assert "cohere async failure" in span.status.description
assert any(
event.name == "exception"
and "cohere async failure" in event.attributes.get("exception.message", "")
for event in span.events
)
assert not any(
"Calling end() on an ended span" in record.message for record in caplog.records
)