From 77792df3ac0b45aac6bf1f3943aeaf4b70cf1766 Mon Sep 17 00:00:00 2001 From: Arjen Nienhuis Date: Wed, 8 May 2024 10:02:29 +0200 Subject: [PATCH 1/3] Add support for add_note() --- sentry_sdk/utils.py | 6 +++++- tests/test_basics.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) 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" + ) From 5cd1315d1e98a9aaa414eb75088c2f89cabf398d Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Mon, 7 Oct 2024 15:20:54 +0200 Subject: [PATCH 2/3] Ignore non-str notes --- sentry_sdk/utils.py | 10 ++++++---- tests/test_basics.py | 9 ++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 336e171222..d7f654d9b2 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -717,10 +717,12 @@ def get_error_message(exc_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]) + ) # type: str + + notes = getattr(exc_value, "__notes__", None) # type: object + if isinstance(notes, list) and len(notes) > 0: + value += "\n" + "\n".join(note for note in notes if isinstance(note, str)) + return value diff --git a/tests/test_basics.py b/tests/test_basics.py index 7af1c18157..91addc6219 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -1008,13 +1008,14 @@ def test_notes(sentry_init, capture_events): try: e = ValueError("aha!") e.add_note("Test 123") + e.add_note("another note") raise e except Exception: capture_exception() (event,) = events - assert event["exception"]["values"][0]["value"] == "aha!\nTest 123" + assert event["exception"]["values"][0]["value"] == "aha!\nTest 123\nanother note" @pytest.mark.skipif(sys.version_info < (3, 11), reason="add_note() not supported") @@ -1033,13 +1034,11 @@ def __str__(self): e.add_note("note 1") e.__notes__.append(Note2()) # type: ignore e.add_note("note 3") + e.__notes__.append(2) # type: ignore raise e except Exception: capture_exception() (event,) = events - assert ( - event["exception"]["values"][0]["value"] - == "aha!\nnote 1\n\nnote 3" - ) + assert event["exception"]["values"][0]["value"] == "aha!\nnote 1\nnote 3" From bc3bfb3b8951c35deebc1598160cc53e0fca778b Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Tue, 8 Oct 2024 09:32:07 +0200 Subject: [PATCH 3/3] minor tweaks --- sentry_sdk/utils.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index d7f654d9b2..3c86564ef8 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -713,17 +713,21 @@ def get_errno(exc_value): def get_error_message(exc_value): # type: (Optional[BaseException]) -> str - value = ( + message = ( getattr(exc_value, "message", "") or getattr(exc_value, "detail", "") or safe_str(exc_value) ) # type: str + # __notes__ should be a list of strings when notes are added + # via add_note, but can be anything else if __notes__ is set + # directly. We only support strings in __notes__, since that + # is the correct use. notes = getattr(exc_value, "__notes__", None) # type: object if isinstance(notes, list) and len(notes) > 0: - value += "\n" + "\n".join(note for note in notes if isinstance(note, str)) + message += "\n" + "\n".join(note for note in notes if isinstance(note, str)) - return value + return message def single_exception_from_error_tuple(