diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 7369afb420..f0d24ddb39 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -666,7 +666,7 @@ def set_http_status(self, http_status): # type: (int) -> None self.set_tag( "http.status_code", str(http_status) - ) # we keep this for backwards compatibility + ) # TODO-neel remove in major, we keep this for backwards compatibility self.set_data(SPANDATA.HTTP_STATUS_CODE, http_status) self.set_status(get_span_status_from_http_code(http_status)) @@ -729,6 +729,8 @@ def to_json(self): } # type: Dict[str, Any] if self.status: + rv["status"] = self.status + # TODO-neel remove redundant tag in major self._tags["status"] = self.status if len(self._measurements) > 0: diff --git a/tests/integrations/anthropic/test_anthropic.py b/tests/integrations/anthropic/test_anthropic.py index d4941ad0f4..1fe2ff5d28 100644 --- a/tests/integrations/anthropic/test_anthropic.py +++ b/tests/integrations/anthropic/test_anthropic.py @@ -722,6 +722,7 @@ def test_span_status_error(sentry_init, capture_events): (error, transaction) = events assert error["level"] == "error" + assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" @@ -745,6 +746,7 @@ async def test_span_status_error_async(sentry_init, capture_events): (error, transaction) = events assert error["level"] == "error" + assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" diff --git a/tests/integrations/cohere/test_cohere.py b/tests/integrations/cohere/test_cohere.py index 3d9ed0722e..9ff56ed697 100644 --- a/tests/integrations/cohere/test_cohere.py +++ b/tests/integrations/cohere/test_cohere.py @@ -181,6 +181,7 @@ def test_span_status_error(sentry_init, capture_events): (error, transaction) = events assert error["level"] == "error" + assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" diff --git a/tests/integrations/huggingface_hub/test_huggingface_hub.py b/tests/integrations/huggingface_hub/test_huggingface_hub.py index e15c75cb6a..f0af26395a 100644 --- a/tests/integrations/huggingface_hub/test_huggingface_hub.py +++ b/tests/integrations/huggingface_hub/test_huggingface_hub.py @@ -792,6 +792,7 @@ def test_chat_completion_api_error( assert span["op"] == "gen_ai.chat" assert span["description"] == "chat test-model" assert span["origin"] == "auto.ai.huggingface_hub" + assert span["status"] == "internal_error" assert span.get("tags", {}).get("status") == "internal_error" assert ( @@ -835,6 +836,7 @@ def test_span_status_error(sentry_init, capture_events, mock_hf_api_with_errors) assert sp["op"] == "http.client" assert span is not None + assert span["status"] == "internal_error" assert span["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" diff --git a/tests/integrations/langchain/test_langchain.py b/tests/integrations/langchain/test_langchain.py index d0d4e62941..9f74e5f47c 100644 --- a/tests/integrations/langchain/test_langchain.py +++ b/tests/integrations/langchain/test_langchain.py @@ -347,6 +347,7 @@ def test_span_status_error(sentry_init, capture_events): (error, transaction) = events assert error["level"] == "error" + assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" diff --git a/tests/integrations/langgraph/test_langgraph.py b/tests/integrations/langgraph/test_langgraph.py index 7cb86a5b03..df574dd2c3 100644 --- a/tests/integrations/langgraph/test_langgraph.py +++ b/tests/integrations/langgraph/test_langgraph.py @@ -403,6 +403,7 @@ def original_invoke(self, *args, **kwargs): assert len(invoke_spans) == 1 invoke_span = invoke_spans[0] + assert invoke_span.get("status") == "internal_error" assert invoke_span.get("tags", {}).get("status") == "internal_error" @@ -436,6 +437,7 @@ async def run_error_test(): assert len(invoke_spans) == 1 invoke_span = invoke_spans[0] + assert invoke_span.get("status") == "internal_error" assert invoke_span.get("tags", {}).get("status") == "internal_error" diff --git a/tests/integrations/mcp/test_mcp.py b/tests/integrations/mcp/test_mcp.py index 508aea5a3a..4415467cd7 100644 --- a/tests/integrations/mcp/test_mcp.py +++ b/tests/integrations/mcp/test_mcp.py @@ -300,6 +300,7 @@ def failing_tool(tool_name, arguments): # Error flag should be set for tools assert span["data"][SPANDATA.MCP_TOOL_RESULT_IS_ERROR] is True + assert span["status"] == "internal_error" assert span["tags"]["status"] == "internal_error" diff --git a/tests/integrations/openai/test_openai.py b/tests/integrations/openai/test_openai.py index 604480702f..814289c887 100644 --- a/tests/integrations/openai/test_openai.py +++ b/tests/integrations/openai/test_openai.py @@ -440,6 +440,7 @@ def test_span_status_error(sentry_init, capture_events): (error, transaction) = events assert error["level"] == "error" + assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" diff --git a/tests/integrations/openai_agents/test_openai_agents.py b/tests/integrations/openai_agents/test_openai_agents.py index 46197ae855..dd216d8a90 100644 --- a/tests/integrations/openai_agents/test_openai_agents.py +++ b/tests/integrations/openai_agents/test_openai_agents.py @@ -645,6 +645,7 @@ async def test_error_handling(sentry_init, capture_events, test_agent): assert ai_client_span["description"] == "chat gpt-4" assert ai_client_span["origin"] == "auto.ai.openai_agents" + assert ai_client_span["status"] == "internal_error" assert ai_client_span["tags"]["status"] == "internal_error" @@ -685,6 +686,7 @@ async def test_error_captures_input_data(sentry_init, capture_events, test_agent ai_client_span = [s for s in spans if s["op"] == "gen_ai.chat"][0] assert ai_client_span["description"] == "chat gpt-4" + assert ai_client_span["status"] == "internal_error" assert ai_client_span["tags"]["status"] == "internal_error" assert "gen_ai.request.messages" in ai_client_span["data"] @@ -724,6 +726,7 @@ async def test_span_status_error(sentry_init, capture_events, test_agent): (error, transaction) = events assert error["level"] == "error" + assert transaction["spans"][0]["status"] == "internal_error" assert transaction["spans"][0]["tags"]["status"] == "internal_error" assert transaction["contexts"]["trace"]["status"] == "internal_error" @@ -827,6 +830,7 @@ async def test_mcp_tool_execution_spans(sentry_init, capture_events, test_agent) ) # Verify no error status since error was None + assert mcp_tool_span.get("status") != "internal_error" assert mcp_tool_span.get("tags", {}).get("status") != "internal_error" @@ -927,6 +931,7 @@ async def test_mcp_tool_execution_with_error(sentry_init, capture_events, test_a assert mcp_tool_span["data"]["gen_ai.tool.output"] is None # Verify error status was set + assert mcp_tool_span["status"] == "internal_error" assert mcp_tool_span["tags"]["status"] == "internal_error" @@ -1218,4 +1223,5 @@ def failing_tool(message: str) -> str: # Verify error status was set (this is the key test for our patch) # The span should be marked as error because the tool execution failed + assert execute_tool_span["status"] == "internal_error" assert execute_tool_span["tags"]["status"] == "internal_error" diff --git a/tests/integrations/pymongo/test_pymongo.py b/tests/integrations/pymongo/test_pymongo.py index 7e6556f85a..0669f73c30 100644 --- a/tests/integrations/pymongo/test_pymongo.py +++ b/tests/integrations/pymongo/test_pymongo.py @@ -99,8 +99,11 @@ def test_transactions(sentry_init, capture_events, mongo_server, with_pii): and "4" not in insert_fail["description"] ) + assert find["status"] == "ok" assert find["tags"]["status"] == "ok" + assert insert_success["status"] == "ok" assert insert_success["tags"]["status"] == "ok" + assert insert_fail["status"] == "internal_error" assert insert_fail["tags"]["status"] == "internal_error" diff --git a/tests/tracing/test_integration_tests.py b/tests/tracing/test_integration_tests.py index 8b5659b694..e0ff123b0d 100644 --- a/tests/tracing/test_integration_tests.py +++ b/tests/tracing/test_integration_tests.py @@ -40,9 +40,11 @@ def test_basic(sentry_init, capture_events, sample_rate): span1, span2 = event["spans"] parent_span = event + assert span1["status"] == "internal_error" assert span1["tags"]["status"] == "internal_error" assert span1["op"] == "foo" assert span1["description"] == "foodesc" + assert "status" not in span2 assert "status" not in span2.get("tags", {}) assert span2["op"] == "bar" assert span2["description"] == "bardesc" @@ -332,6 +334,7 @@ def test_non_error_exceptions( event = events[0] span = event["spans"][0] + assert "status" not in span assert "status" not in span.get("tags", {}) assert "status" not in event["tags"] assert event["contexts"]["trace"]["status"] == "ok" @@ -357,6 +360,7 @@ def test_good_sysexit_doesnt_fail_transaction( event = events[0] span = event["spans"][0] + assert "status" not in span assert "status" not in span.get("tags", {}) assert "status" not in event["tags"] assert event["contexts"]["trace"]["status"] == "ok"