Repository navigation
fix: OTel operation and attempt events lose the original exception.type - #812
nandanadileep wants to merge 4 commits into
Conversation
zhongkechen
left a comment
There was a problem hiding this comment.
I found two cases worth covering in the shared tests: exception groups and custom exception constructors.
| try: | ||
| return cls(message) | ||
| except Exception: # noqa: BLE001 - a class may reject positional args | ||
| exc: BaseException = cls.__new__(cls) |
There was a problem hiding this comment.
ExceptionGroup breaks this fallback too: its __new__ still needs both the message and the contained exceptions. I reproduced this in both views; PluginExecutor catches the TypeError, and the exported operation/attempt span has no exception event.
Could we add an ExceptionGroup regression case and fall back to a plain exception? We're already overriding exception.type and exception.message, so preserving the recorded type doesn't depend on reconstructing the original class.
| resolved: type[BaseException] | None = _resolve_exception_class(type_name) | ||
| cls: type[BaseException] = resolved or _synthesize_exception_class(type_name) | ||
| try: | ||
| return cls(message) |
There was a problem hiding this comment.
This calls the application's exception constructor again just to record the event. With a custom exception that increments a counter in __init__, I see another increment for each operation/attempt event in both views. Any logging, metrics, or I/O in that constructor would run again too, including when processing stored error metadata.
I think we can avoid resolving and constructing the original class altogether: pass a plain Exception(message) and keep the explicit type/message/stacktrace attributes below. That would also avoid running application constructors during replay.
Fixes #804.
Preserve the checkpointed
exception.type,exception.message, and stack trace on OpenTelemetry operation and attempt events in both execution and invocation views. Record a plainException(message)with explicit saved attributes, avoiding imports and application exception constructors during telemetry recording or replay. This also supportsExceptionGroupandBaseExceptionGroup, whose constructors require more than a message.Shared regression tests cover built-in and unknown exception types, exception groups, constructor side effects, and replayed metadata. The execution view continues to suppress duplicate replayed operation spans.
Validation on Python 3.13.14:
hatch run dev-otel:test -q --tb=short: 796 passed, including integration tests.hatch run dev-otel:typecheck: passed (44 source files).hatch fmt --checkfrom the OTel package: passed.git diff --check: passed.AI-assisted contribution: OpenCode using Autoloops authored the initial patch; Codex implemented the review follow-up and ran the local checks above. No human review is claimed.