Skip to content

Commit 2d5f7ef

Browse files
committed
Added support for looking up hook callables for the Sentry reporter
1 parent 4e81ef4 commit 2d5f7ef

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

docs/versionhistory.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ Version history
33

44
This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
55

6+
**UNRELEASED**
7+
8+
- Added support for looking up hook callables for the Sentry reporter
9+
610
**2.1.0** (2023-06-10)
711

812
- Removed explicit run-time argument type checks and the ``typeguard`` dependency

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ test = [
4242
"pytest",
4343
"pytest-asyncio",
4444
"pytest-cov",
45+
"pytest-mock",
4546
]
4647
doc = [
4748
"asphalt-exceptions[sentry,raygun]",

src/asphalt/exceptions/reporters/sentry.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import annotations
22

33
import logging
4+
import sys
5+
from collections.abc import Callable
46
from typing import Any, Sequence
57

68
import sentry_sdk
@@ -9,8 +11,20 @@
911

1012
from asphalt.exceptions.api import ExceptionReporter
1113

14+
if sys.version_info >= (3, 10):
15+
from typing import TypeAlias
16+
else:
17+
from typing_extensions import TypeAlias
18+
1219
logger = logging.getLogger(__name__)
1320

21+
Event: TypeAlias = "dict[str, Any]"
22+
Hint: TypeAlias = "dict[str, Any]"
23+
Breadcrumb: TypeAlias = "dict[str, Any]"
24+
BreadcrumbHint: TypeAlias = "dict[str, Any]"
25+
EventProcessor: TypeAlias = "Callable[[Event, Hint], Event | None]"
26+
BreadcrumbProcessor: TypeAlias = "Callable[[Breadcrumb, BreadcrumbHint], Breadcrumb | None]"
27+
1428

1529
class SentryExceptionReporter(ExceptionReporter):
1630
"""
@@ -31,7 +45,11 @@ class SentryExceptionReporter(ExceptionReporter):
3145
should be a mapping of keyword arguments to their values.
3246
3347
The extras passed to this backend are passed to :func:`sentry_sdk.capture_exception` as keyword
34-
arguments.
48+
arguments. Two such options have been special cased and can be looked up as a
49+
``module:varname`` reference:
50+
51+
- ``before_send``
52+
- ``before_breadcrumb``
3553
3654
For more information, see the `Sentry SDK documentation`_.
3755
@@ -40,8 +58,22 @@ class SentryExceptionReporter(ExceptionReporter):
4058
"""
4159

4260
def __init__(
43-
self, integrations: Sequence[Integration | dict[str, Any]] = (), **options
61+
self,
62+
integrations: Sequence[Integration | dict[str, Any]] = (),
63+
before_send: EventProcessor | str | None = None,
64+
before_breadcrumb: BreadcrumbProcessor | str | None = None,
65+
**options,
4466
) -> None:
67+
if isinstance(before_send, str):
68+
_before_send: EventProcessor | None = resolve_reference(before_send)
69+
else:
70+
_before_send = before_send
71+
72+
if isinstance(before_breadcrumb, str):
73+
_before_breadcrumb: BreadcrumbProcessor | None = resolve_reference(before_breadcrumb)
74+
else:
75+
_before_breadcrumb = before_breadcrumb
76+
4577
options.setdefault("environment", "development" if __debug__ else "production")
4678

4779
integrations_: list[Integration] = []
@@ -54,7 +86,12 @@ def __init__(
5486

5587
integrations_.append(integration)
5688

57-
sentry_sdk.init(integrations=integrations_, **options)
89+
sentry_sdk.init(
90+
integrations=integrations_,
91+
before_send=_before_send,
92+
before_breadcrumb=_before_breadcrumb,
93+
**options,
94+
)
5895

5996
def report_exception(
6097
self,

tests/reporters/test_sentry.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44
from asphalt.core import Context
5+
from pytest_mock import MockerFixture
56
from sentry_sdk import Transport
67
from sentry_sdk.integrations import Integration
78

@@ -18,6 +19,14 @@ def setup_once():
1819
pass
1920

2021

22+
def before_send(event, hint):
23+
pass
24+
25+
26+
def before_breadcrumb(breadcrumb, hint):
27+
pass
28+
29+
2130
@pytest.mark.asyncio
2231
async def test_sentry():
2332
exception = None
@@ -43,3 +52,16 @@ def test_integrations():
4352
SentryExceptionReporter(
4453
dsn="http://username:[email protected]/000000", integrations=integrations
4554
)
55+
56+
57+
def test_hook_lookup(mocker: MockerFixture):
58+
init_func = mocker.patch("sentry_sdk.init")
59+
SentryExceptionReporter(
60+
before_send=f"{__name__}:before_send", before_breadcrumb=f"{__name__}:before_breadcrumb"
61+
)
62+
init_func.assert_called_once_with(
63+
integrations=[],
64+
before_send=before_send,
65+
before_breadcrumb=before_breadcrumb,
66+
environment="development",
67+
)

0 commit comments

Comments
 (0)