1"""OTel-related helpers shared across Plain packages."""
2
3from __future__ import annotations
4
5
6def format_exception_type(exc: BaseException) -> str:
7 """Format an exception's class name per OTel semantic conventions.
8
9 Returns the fully-qualified class name (``module.qualname``) for
10 third-party and user-defined exceptions. Python builtins drop the
11 ``builtins.`` prefix so common exceptions stay short.
12
13 Used for the ``error.type`` span attribute, which SHOULD match the
14 ``exception.type`` attribute written by ``span.record_exception()``.
15
16 Examples::
17
18 ValueError -> "ValueError"
19 django.db.utils.IntegrityError -> "django.db.utils.IntegrityError"
20 myapp.errors.BillingError -> "myapp.errors.BillingError"
21 """
22 cls = type(exc)
23 if cls.__module__ == "builtins":
24 return cls.__qualname__
25 return f"{cls.__module__}.{cls.__qualname__}"