diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 44cb98bfed..336e171222 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -713,11 +713,15 @@ def get_errno(exc_value): def get_error_message(exc_value): # type: (Optional[BaseException]) -> str - return ( + value = ( getattr(exc_value, "message", "") or getattr(exc_value, "detail", "") or safe_str(exc_value) ) + notes = getattr(exc_value, "__notes__", []) + if notes: + value = "\n".join([value] + [safe_str(note) for note in notes]) + return value def single_exception_from_error_tuple( diff --git a/tests/test_basics.py b/tests/test_basics.py index 139f919a68..7af1c18157 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -999,3 +999,47 @@ def test_hub_current_deprecation_warning(): def test_hub_main_deprecation_warnings(): with pytest.warns(sentry_sdk.hub.SentryHubDeprecationWarning): Hub.main + + +@pytest.mark.skipif(sys.version_info < (3, 11), reason="add_note() not supported") +def test_notes(sentry_init, capture_events): + sentry_init() + events = capture_events() + try: + e = ValueError("aha!") + e.add_note("Test 123") + raise e + except Exception: + capture_exception() + + (event,) = events + + assert event["exception"]["values"][0]["value"] == "aha!\nTest 123" + + +@pytest.mark.skipif(sys.version_info < (3, 11), reason="add_note() not supported") +def test_notes_safe_str(sentry_init, capture_events): + class Note2: + def __repr__(self): + raise TypeError + + def __str__(self): + raise TypeError + + sentry_init() + events = capture_events() + try: + e = ValueError("aha!") + e.add_note("note 1") + e.__notes__.append(Note2()) # type: ignore + e.add_note("note 3") + raise e + except Exception: + capture_exception() + + (event,) = events + + assert ( + event["exception"]["values"][0]["value"] + == "aha!\nnote 1\n\nnote 3" + )