mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-11 03:12:55 +00:00
Keep exception text out of stored and exported span errors
Span.fail stored the exception message in span.error, which is stored and exported whatever the content settings; a provider's content-filter error can quote the prompt. span.error now holds the exception type, and the message is a capture-gated preview, like tool errors already were. A yielded stream error on the agent span is treated the same way.
This commit is contained in:
1 parent
0bbbac0eb2
commit
0591580014
4 files changed
+32
-7
No files matched your search
+3
-1
@@ -234,7 +234,9 @@ def _end_agent_span(span: Any, context: "LogContext", *, error: BaseException |
|
||||
span.end(error=error, attributes=attributes)
|
||||
elif context.stream_error:
|
||||
span.set(**attributes, **{"error.type": "StreamError"})
|
||||
span.error = context.stream_error
|
||||
# The error event's text is gated like any other content.
|
||||
span.preview("error", context.stream_error)
|
||||
span.error = "StreamError"
|
||||
span.end(tracing.STATUS_ERROR)
|
||||
else:
|
||||
span.end(None if completed else tracing.STATUS_CANCELLED, attributes=attributes)
|
||||
|
||||
+13
-2
@@ -146,10 +146,21 @@ class Span:
|
||||
return self
|
||||
|
||||
def fail(self, exc: BaseException) -> "Span":
|
||||
"""Record ``exc`` on the span without ending it."""
|
||||
"""Record ``exc`` on the span without ending it.
|
||||
|
||||
``error`` and ``error.type`` hold only the exception type: they are
|
||||
stored and exported whatever the content settings, and exception text
|
||||
can quote the prompt (a provider's content-filter error) or a tool
|
||||
result. The message itself becomes the capture-gated ``error``
|
||||
preview, dropped with every other preview when capture is off or a
|
||||
guardrail fired.
|
||||
"""
|
||||
self.status = STATUS_ERROR
|
||||
self.error = str(exc)[:500] or type(exc).__name__
|
||||
self.error = type(exc).__name__
|
||||
self.attributes["error.type"] = type(exc).__name__
|
||||
message = str(exc)
|
||||
if message:
|
||||
self.preview("error", message)
|
||||
return self
|
||||
|
||||
def end(
|
||||
|
||||
@@ -398,8 +398,6 @@ class TestAccumulateResponseSummary:
|
||||
assert ctx.tool_call_count == 2
|
||||
|
||||
|
||||
|
||||
|
||||
class TestLogActivityTraceSpan:
|
||||
"""``@log_activity`` opens the ``invoke_agent`` span for every agent run."""
|
||||
|
||||
@@ -475,7 +473,8 @@ class TestLogActivityTraceSpan:
|
||||
with patch("docsgpt.logging._log_activity_to_db"), tracing.activate(trace):
|
||||
list(gen(self._Agent()))
|
||||
assert trace.spans[0].status == "error"
|
||||
assert trace.spans[0].error == "node failed"
|
||||
assert trace.spans[0].error == "StreamError"
|
||||
assert trace.spans[0].previews["error"] == "node failed"
|
||||
|
||||
def test_raised_error_marks_span_error(self):
|
||||
from docsgpt import tracing
|
||||
|
||||
@@ -133,7 +133,20 @@ class TestNesting:
|
||||
span = trace.spans[0]
|
||||
assert span.status == "error"
|
||||
assert span.attributes["error.type"] == "ValueError"
|
||||
assert span.error == "boom"
|
||||
# Exception text can quote a prompt: it is a capture-gated preview,
|
||||
# never the always-stored/exported ``error``.
|
||||
assert span.error == "ValueError"
|
||||
assert span.previews["error"] == "boom"
|
||||
|
||||
def test_exception_text_is_dropped_when_capture_is_off(self, monkeypatch):
|
||||
monkeypatch.setattr(settings, "TRACES_CAPTURE_CONTENT", False)
|
||||
trace = tracing.start_trace(source="stream")
|
||||
with tracing.activate(trace):
|
||||
with pytest.raises(ValueError):
|
||||
with tracing.span(tracing.KIND_LLM, "chat"):
|
||||
raise ValueError("content filter: <the user's prompt>")
|
||||
trace.finish()
|
||||
assert "the user's prompt" not in str(trace.to_record())
|
||||
|
||||
def test_generator_exit_marks_span_cancelled(self):
|
||||
trace = tracing.start_trace(source="stream")
|
||||
|
||||
Reference in new issue
Block a user