diff --git a/swh/loader/core/loader.py b/swh/loader/core/loader.py --- a/swh/loader/core/loader.py +++ b/swh/loader/core/loader.py @@ -336,6 +336,9 @@ in :meth:`prepare` method. """ + sentry_sdk.set_tag("swh.loader.origin_url", self.origin.url[0:200]) + sentry_sdk.set_tag("swh.loader.visit_type", self.visit_type) + try: with self.statsd_timed("pre_cleanup"): self.pre_cleanup() diff --git a/swh/loader/core/tests/conftest.py b/swh/loader/core/tests/conftest.py new file mode 100644 --- /dev/null +++ b/swh/loader/core/tests/conftest.py @@ -0,0 +1,44 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import pytest +import sentry_sdk + + +@pytest.fixture +def sentry_init(): + # Inspired by + # https://github.com/getsentry/sentry-python/blob/1.5.9/tests/conftest.py#L168-L184 + + initialized = False + + def inner(*a, **kw): + nonlocal initialized + assert not initialized, "already initialized" + initialized = True + hub = sentry_sdk.Hub.current + client = sentry_sdk.Client(*a, **kw) + hub.bind_client(client) + client.transport = TestTransport() + + class TestTransport: + def __init__(self): + self.events = [] + self.envelopes = [] + + def capture_event(self, event): + self.events.append(event) + + def capture_envelope(self, envelope): + self.envelopes.append(envelope) + + with sentry_sdk.Hub(None): + yield inner + + +@pytest.fixture +def sentry_events(monkeypatch, sentry_init): + sentry_init() + return sentry_sdk.Hub.current.client.transport.events diff --git a/swh/loader/core/tests/test_loader.py b/swh/loader/core/tests/test_loader.py --- a/swh/loader/core/tests/test_loader.py +++ b/swh/loader/core/tests/test_loader.py @@ -479,3 +479,22 @@ assert result == {"status": "uneventful"} _check_load_failure(caplog, loader, NotFound, "Unknown origin!", status="not_found") + + +class DummyLoaderWithError(DummyBaseLoader): + def prepare(self, *args, **kwargs): + raise Exception("error") + + +class DummyDVCSLoaderWithError(DummyDVCSLoader, BaseLoader): + def prepare(self, *args, **kwargs): + raise Exception("error") + + +@pytest.mark.parametrize("loader_cls", [DummyLoaderWithError, DummyDVCSLoaderWithError]) +def test_loader_sentry_tags_on_error(swh_storage, sentry_events, loader_cls): + loader = loader_cls(swh_storage) + loader.load() + sentry_tags = sentry_events[0]["tags"] + assert sentry_tags.get("swh.loader.origin_url") == ORIGIN.url + assert sentry_tags.get("swh.loader.visit_type") == DummyLoader.visit_type