open-telemetry / open-telemetry/opentelemetry-python

Fragile reporting for poorly implemented exceptions

Open
#2,683 2 comments 3 reactions 1 assignee View on GitHub

@kennykguo is already working on this.

Since Jan 10, 2024.

bug
Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Describe your environment
Python 3.9, Cornice 3.6, Pyramid 10.7

Steps to reproduce
Attempt to validate a request using an invalid json payload.

A more testable reproduction is raising an exception with a broken implementation of __str__.

class FooException(Exception):
  def __str__(self):
    return self.foo

What is the expected behavior?
The failure to parse the exception for its attributes results in a new uncaught exception.

What is the actual behavior?
Cornice creates a _JSONError exception (based on HttpException via HttpError) which manages to avoid setting the detail attribute. Since detail is assumed to exist for the implementation of Pyramid's HttpException.__str__() an AttributeError exception is thrown at https://github.com/open-telemetry/opentelemetry-python/blob/main/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L944.

File "/opt/foo/python/lib/python3.9/site-packages/opentelemetry/instrumentation/pyramid/callbacks.py", line 192, in trace_tween
    activation.__exit__(
  File "/opt/foo/python/lib/python3.9/contextlib.py", line 135, in __exit__
    self.gen.throw(type, value, traceback)
  File "/opt/foo/python/lib/python3.9/site-packages/opentelemetry/trace/__init__.py", line 570, in use_span
    span.record_exception(exc)
  File "/opt/foo/python/lib/python3.9/site-packages/opentelemetry/sdk/trace/__init__.py", line 927, in record_exception
    "exception.message": str(exception),
  File "/opt/foo/python/lib/python3.9/site-packages/pyramid/httpexceptions.py", line 253, in __str__
    return str(self.detail) if self.detail else self.explanation
AttributeError: '_JSONError' object has no attribute 'detail'

Additional context
It seems gathering attributes should have a guard around it in the event the exception type has an unresolvable __str__ implementation. Maybe getting the stack using traceback.format_exc() could supplement the provided exception?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.