Coverage for src/backend/InvenTree/InvenTree/sentry.py: 42%
40 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""Configuration for Sentry.io error reporting."""
3from typing import Optional
5from django.conf import settings
6from django.core.exceptions import ValidationError
7from django.http import Http404
8from django.template.exceptions import TemplateSyntaxError
10import rest_framework.exceptions
11import sentry_sdk
12import structlog
13from djmoney.contrib.exchange.exceptions import MissingRate
14from sentry_sdk.integrations.django import DjangoIntegration
16import InvenTree.version
18logger = structlog.get_logger('inventree')
21def default_sentry_dsn():
22 """Return the default Sentry.io DSN for InvenTree."""
23 return 'https://3928ccdba1d34895abde28031fd00100@o378676.ingest.sentry.io/6494600'
26def sentry_ignore_errors(): # pragma: no cover
27 """Return a list of error types to ignore.
29 These error types will *not* be reported to sentry.io.
30 """
31 return [
32 Http404,
33 MissingRate,
34 TemplateSyntaxError,
35 ValidationError,
36 rest_framework.exceptions.AuthenticationFailed,
37 rest_framework.exceptions.NotAuthenticated,
38 rest_framework.exceptions.PermissionDenied,
39 rest_framework.exceptions.ValidationError,
40 ]
43def init_sentry(dsn, sample_rate, tags): # pragma: no cover
44 """Initialize sentry.io error reporting."""
45 logger.info('Initializing sentry.io integration')
47 sentry_sdk.init(
48 dsn=dsn,
49 integrations=[DjangoIntegration()],
50 traces_sample_rate=sample_rate,
51 send_default_pii=True,
52 ignore_errors=sentry_ignore_errors(),
53 release=InvenTree.version.INVENTREE_SW_VERSION,
54 environment='development'
55 if InvenTree.version.isInvenTreeDevelopmentVersion()
56 else 'production',
57 )
59 for key, val in tags.items():
60 sentry_sdk.set_tag(f'inventree_{key}', val)
62 sentry_sdk.set_tag('api', InvenTree.version.inventreeApiVersion())
63 sentry_sdk.set_tag('platform', InvenTree.version.inventreePlatform())
64 sentry_sdk.set_tag('git_branch', InvenTree.version.inventreeBranch())
65 sentry_sdk.set_tag('git_commit', InvenTree.version.inventreeCommitHash())
66 sentry_sdk.set_tag('git_date', InvenTree.version.inventreeCommitDate())
69def report_exception(exc, scope: Optional[dict] = None): # pragma: no cover
70 """Report an exception to sentry.io."""
71 assert settings.TESTING == False, (
72 'report_exception should not be called in testing mode'
73 )
75 # Skip if sentry not enabled, or not configured
76 if not settings.SENTRY_ENABLED or not settings.SENTRY_DSN: 76 ↛ 80line 76 didn't jump to line 80 because the condition on line 76 was always true
77 return
79 # Skip if this error type is in the ignore list
80 if any(isinstance(exc, e) for e in sentry_ignore_errors()):
81 return
83 # Error may also be passed in from the loggingn context
84 if hasattr(exc, 'event'):
85 event = getattr(exc, 'event', None)
87 if any(isinstance(event, e) for e in sentry_ignore_errors()):
88 return
90 try:
91 sentry_sdk.capture_exception(exc, scope=scope)
92 except Exception:
93 logger.warning('Failed to report exception to sentry.io')