Skip to content

Commit c940e5e

Browse files
committed
Make it easier to undertand
1 parent 36cd2c4 commit c940e5e

File tree

1 file changed

+49
-31
lines changed

1 file changed

+49
-31
lines changed

sentry_sdk/utils.py

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -775,14 +775,16 @@ def exceptions_from_error(
775775
):
776776
# type: (...) -> Tuple[int, List[Dict[str, Any]]]
777777
"""
778-
Creates the list of exceptions.
779-
This can include chained exceptions and exceptions from an ExceptionGroup.
780-
781-
See the Exception Interface documentation for more details:
782-
https://develop.sentry.dev/sdk/event-payloads/exception/
778+
Converts the given exception information into the Sentry structured "exception" format.
779+
This will return a list of exceptions in the format of the Exception Interface documentation:
780+
https://develop.sentry.dev/sdk/data-model/event-payloads/exception/
781+
782+
This function can handle:
783+
- simple exceptions
784+
- chained exceptions (raise .. from ..)
785+
- exception groups
783786
"""
784-
785-
parent = single_exception_from_error_tuple(
787+
base_exception = single_exception_from_error_tuple(
786788
exc_type=exc_type,
787789
exc_value=exc_value,
788790
tb=tb,
@@ -793,64 +795,70 @@ def exceptions_from_error(
793795
source=source,
794796
full_stack=full_stack,
795797
)
796-
exceptions = [parent]
798+
exceptions = [base_exception]
797799

798800
parent_id = exception_id
799801
exception_id += 1
800802

801-
should_supress_context = hasattr(exc_value, "__suppress_context__") and exc_value.__suppress_context__ # type: ignore
802-
if should_supress_context:
803-
# Add direct cause.
804-
# The field `__cause__` is set when raised with the exception (using the `from` keyword).
805-
exception_has_cause = (
803+
# Note: __suppress_context__ is True if the exception is raised with the `from` keyword.
804+
should_suppress_context = hasattr(exc_value, "__suppress_context__") and exc_value.__suppress_context__ # type: ignore
805+
if should_suppress_context:
806+
# Explicitly chained exceptions (Like: raise NewException() from OriginalException())
807+
# The field `__cause__` is set to OriginalException
808+
exception_has_explicit_causing_exception = (
806809
exc_value
807810
and hasattr(exc_value, "__cause__")
808811
and exc_value.__cause__ is not None
809812
)
810-
if exception_has_cause:
811-
cause = exc_value.__cause__ # type: ignore
813+
if exception_has_explicit_causing_exception:
814+
causing_exception = exc_value.__cause__ # type: ignore
815+
812816
(exception_id, child_exceptions) = exceptions_from_error(
813-
exc_type=type(cause),
814-
exc_value=cause,
815-
tb=getattr(cause, "__traceback__", None),
817+
exc_type=type(causing_exception),
818+
exc_value=causing_exception,
819+
tb=getattr(causing_exception, "__traceback__", None),
816820
client_options=client_options,
817821
mechanism=mechanism,
818822
exception_id=exception_id,
823+
# parent_id=parent_id, TODO: why is this not set?
819824
source="__cause__",
820825
full_stack=full_stack,
821826
)
822827
exceptions.extend(child_exceptions)
823828

824829
else:
825-
# Add indirect cause.
826-
# The field `__context__` is assigned if another exception occurs while handling the exception.
827-
exception_has_content = (
830+
# Implicitly chained exceptions (when an exception occurs while handling another exception)
831+
# The field `__context__` is set in the exception that occurs while handling another exception,
832+
# to the other exception.
833+
exception_has_implicit_causing_exception = (
828834
exc_value
829835
and hasattr(exc_value, "__context__")
830836
and exc_value.__context__ is not None
831837
)
832-
if exception_has_content:
833-
context = exc_value.__context__ # type: ignore
838+
if exception_has_implicit_causing_exception:
839+
causing_exception = exc_value.__context__ # type: ignore
840+
834841
(exception_id, child_exceptions) = exceptions_from_error(
835-
exc_type=type(context),
836-
exc_value=context,
837-
tb=getattr(context, "__traceback__", None),
842+
exc_type=type(causing_exception),
843+
exc_value=causing_exception,
844+
tb=getattr(causing_exception, "__traceback__", None),
838845
client_options=client_options,
839846
mechanism=mechanism,
840847
exception_id=exception_id,
848+
# parent_id=parent_id, TODO: why is this not set?
841849
source="__context__",
842850
full_stack=full_stack,
843851
)
844852
exceptions.extend(child_exceptions)
845853

846-
# Add exceptions from an ExceptionGroup.
854+
# Add child exceptions from an ExceptionGroup.
847855
is_exception_group = exc_value and hasattr(exc_value, "exceptions")
848856
if is_exception_group:
849-
for idx, e in enumerate(exc_value.exceptions): # type: ignore
857+
for idx, causing_exception in enumerate(exc_value.exceptions): # type: ignore
850858
(exception_id, child_exceptions) = exceptions_from_error(
851-
exc_type=type(e),
852-
exc_value=e,
853-
tb=getattr(e, "__traceback__", None),
859+
exc_type=type(causing_exception),
860+
exc_value=causing_exception,
861+
tb=getattr(causing_exception, "__traceback__", None),
854862
client_options=client_options,
855863
mechanism=mechanism,
856864
exception_id=exception_id,
@@ -870,8 +878,15 @@ def exceptions_from_error_tuple(
870878
full_stack=None, # type: Optional[list[dict[str, Any]]]
871879
):
872880
# type: (...) -> List[Dict[str, Any]]
881+
"""
882+
Convert Python's exception information into Sentry's structured "exception" format in the event.
883+
See https://develop.sentry.dev/sdk/data-model/event-payloads/exception/
884+
This is the entry point for the exception handling.
885+
"""
886+
# unpack the exception info tuple
873887
exc_type, exc_value, tb = exc_info
874888

889+
# let exceptions_from_error do the actual work
875890
_, exceptions = exceptions_from_error(
876891
exc_type=exc_type,
877892
exc_value=exc_value,
@@ -883,6 +898,9 @@ def exceptions_from_error_tuple(
883898
full_stack=full_stack,
884899
)
885900

901+
# make sure the exceptions are sorted
902+
# from the innermost (oldest)
903+
# to the outermost (newest) exception
886904
exceptions.reverse()
887905

888906
return exceptions

0 commit comments

Comments
 (0)