t-bug-catcher 0.6.13__tar.gz → 1.1.1.2766__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- t_bug_catcher-1.1.1.2766/MANIFEST.in +1 -0
- t_bug_catcher-1.1.1.2766/PKG-INFO +9 -0
- t_bug_catcher-1.1.1.2766/backend_shim.py +31 -0
- t_bug_catcher-1.1.1.2766/setup.cfg +4 -0
- t_bug_catcher-1.1.1.2766/setup.py +27 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/__init__.py +4 -9
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/bug_catcher.py +55 -37
- t_bug_catcher-1.1.1.2766/t_bug_catcher/bug_snag.py +136 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/config.py +6 -4
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/jira.py +334 -162
- t_bug_catcher-1.1.1.2766/t_bug_catcher/py.typed +0 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/stack_saver.py +26 -14
- t_bug_catcher-1.1.1.2766/t_bug_catcher/utils/__init__.py +5 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/utils/common.py +58 -33
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/utils/logger.py +2 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/workitems.py +2 -2
- t_bug_catcher-1.1.1.2766/t_bug_catcher.egg-info/PKG-INFO +9 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher.egg-info/SOURCES.txt +4 -8
- t_bug_catcher-1.1.1.2766/t_bug_catcher.egg-info/requires.txt +3 -0
- t_bug_catcher-0.6.13/MANIFEST.in +0 -1
- t_bug_catcher-0.6.13/PKG-INFO +0 -70
- t_bug_catcher-0.6.13/README.rst +0 -44
- t_bug_catcher-0.6.13/pyproject.toml +0 -7
- t_bug_catcher-0.6.13/requirements.txt +0 -3
- t_bug_catcher-0.6.13/setup.cfg +0 -17
- t_bug_catcher-0.6.13/setup.py +0 -34
- t_bug_catcher-0.6.13/t_bug_catcher/bug_snag.py +0 -90
- t_bug_catcher-0.6.13/t_bug_catcher/resources/whispers_config.yml +0 -44
- t_bug_catcher-0.6.13/t_bug_catcher/utils/__init__.py +0 -2
- t_bug_catcher-0.6.13/t_bug_catcher.egg-info/PKG-INFO +0 -70
- t_bug_catcher-0.6.13/t_bug_catcher.egg-info/requires.txt +0 -3
- t_bug_catcher-0.6.13/tests/test_t_bug_catcher.py +0 -93
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher/exceptions.py +0 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher.egg-info/dependency_links.txt +0 -0
- /t_bug_catcher-0.6.13/t_bug_catcher.egg-info/not-zip-safe → /t_bug_catcher-1.1.1.2766/t_bug_catcher.egg-info/namespace_packages.txt +0 -0
- {t_bug_catcher-0.6.13 → t_bug_catcher-1.1.1.2766}/t_bug_catcher.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include *.py
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
# DO NOT EDIT THIS FILE -- AUTOGENERATED BY PANTS
|
|
3
|
+
|
|
4
|
+
import errno
|
|
5
|
+
import os
|
|
6
|
+
import setuptools.build_meta
|
|
7
|
+
|
|
8
|
+
backend = setuptools.build_meta.__legacy__
|
|
9
|
+
|
|
10
|
+
dist_dir = "dist/"
|
|
11
|
+
build_wheel = True
|
|
12
|
+
build_sdist = True
|
|
13
|
+
wheel_config_settings = {
|
|
14
|
+
}
|
|
15
|
+
sdist_config_settings = {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# Python 2.7 doesn't have the exist_ok arg on os.makedirs().
|
|
19
|
+
try:
|
|
20
|
+
os.makedirs(dist_dir)
|
|
21
|
+
except OSError as e:
|
|
22
|
+
if e.errno != errno.EEXIST:
|
|
23
|
+
raise
|
|
24
|
+
|
|
25
|
+
wheel_path = backend.build_wheel(dist_dir, wheel_config_settings) if build_wheel else None
|
|
26
|
+
sdist_path = backend.build_sdist(dist_dir, sdist_config_settings) if build_sdist else None
|
|
27
|
+
|
|
28
|
+
if wheel_path:
|
|
29
|
+
print("wheel: {wheel_path}".format(wheel_path=wheel_path))
|
|
30
|
+
if sdist_path:
|
|
31
|
+
print("sdist: {sdist_path}".format(sdist_path=sdist_path))
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
# DO NOT EDIT THIS FILE -- AUTOGENERATED BY PANTS
|
|
3
|
+
# Target: libraries/t_bug_catcher:t-bug-catcher
|
|
4
|
+
|
|
5
|
+
from setuptools import setup
|
|
6
|
+
|
|
7
|
+
setup(**{
|
|
8
|
+
'install_requires': (
|
|
9
|
+
'bugsnag==4.8.0',
|
|
10
|
+
'requests==2.32.5',
|
|
11
|
+
'retry==0.9.2',
|
|
12
|
+
),
|
|
13
|
+
'name': 't-bug-catcher',
|
|
14
|
+
'namespace_packages': (
|
|
15
|
+
),
|
|
16
|
+
'package_data': {
|
|
17
|
+
't_bug_catcher': (
|
|
18
|
+
'py.typed',
|
|
19
|
+
),
|
|
20
|
+
},
|
|
21
|
+
'packages': (
|
|
22
|
+
't_bug_catcher',
|
|
23
|
+
't_bug_catcher.utils',
|
|
24
|
+
),
|
|
25
|
+
'python_requires': '>=3.12,<3.14',
|
|
26
|
+
'version': '1.1.1.2766',
|
|
27
|
+
})
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
"""Top-level package for t-bug-catcher."""
|
|
2
2
|
|
|
3
|
-
__author__ = """Thoughtful"""
|
|
4
|
-
__email__ = "support@thoughtful.ai"
|
|
5
|
-
# fmt: off
|
|
6
|
-
__version__ = '0.6.13'
|
|
7
|
-
# fmt: on
|
|
8
|
-
|
|
9
3
|
from .bug_catcher import (
|
|
10
|
-
configure,
|
|
11
|
-
report_error,
|
|
12
4
|
attach_file_to_exception,
|
|
5
|
+
configure,
|
|
6
|
+
get_errors_count,
|
|
13
7
|
install_sys_hook,
|
|
8
|
+
report_error,
|
|
14
9
|
uninstall_sys_hook,
|
|
15
|
-
get_errors_count,
|
|
16
10
|
)
|
|
17
11
|
|
|
12
|
+
|
|
18
13
|
__all__ = [
|
|
19
14
|
"configure",
|
|
20
15
|
"report_error",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""JiraPoster class for interacting with the Jira API."""
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
|
-
import os
|
|
5
4
|
import sys
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
6
7
|
from types import TracebackType
|
|
7
|
-
from typing import List, Optional
|
|
8
8
|
|
|
9
9
|
from .bug_snag import BugSnag
|
|
10
10
|
from .config import CONFIG
|
|
@@ -29,10 +29,10 @@ class Configurator:
|
|
|
29
29
|
login: str,
|
|
30
30
|
api_token: str,
|
|
31
31
|
project_key: str,
|
|
32
|
-
webhook_url:
|
|
33
|
-
webhook_secret:
|
|
34
|
-
default_assignee:
|
|
35
|
-
):
|
|
32
|
+
webhook_url: str | None = None,
|
|
33
|
+
webhook_secret: str | None = None,
|
|
34
|
+
default_assignee: str | None = None,
|
|
35
|
+
) -> None:
|
|
36
36
|
"""Configures the JiraPoster and BugSnag classes.
|
|
37
37
|
|
|
38
38
|
Args:
|
|
@@ -55,7 +55,7 @@ class Configurator:
|
|
|
55
55
|
default_assignee=default_assignee,
|
|
56
56
|
)
|
|
57
57
|
|
|
58
|
-
def bugsnag(self, api_key: str):
|
|
58
|
+
def bugsnag(self, api_key: str) -> None:
|
|
59
59
|
"""Configures the BugSnag class.
|
|
60
60
|
|
|
61
61
|
Args:
|
|
@@ -67,12 +67,12 @@ class Configurator:
|
|
|
67
67
|
self.__bug_snag_configured = self.__bug_snag.config(api_key=api_key)
|
|
68
68
|
|
|
69
69
|
@property
|
|
70
|
-
def is_jira_configured(self):
|
|
70
|
+
def is_jira_configured(self) -> bool:
|
|
71
71
|
"""Checks if the JiraPoster class has been configured."""
|
|
72
72
|
return self.__jira_configured
|
|
73
73
|
|
|
74
74
|
@property
|
|
75
|
-
def is_bugsnag_configured(self):
|
|
75
|
+
def is_bugsnag_configured(self) -> bool:
|
|
76
76
|
"""Checks if the BugSnag class has been configured."""
|
|
77
77
|
return self.__bug_snag_configured
|
|
78
78
|
|
|
@@ -98,24 +98,24 @@ class BugCatcher:
|
|
|
98
98
|
self.__errors_count = 0
|
|
99
99
|
|
|
100
100
|
@property
|
|
101
|
-
def configure(self):
|
|
101
|
+
def configure(self) -> Configurator:
|
|
102
102
|
"""Configures the JiraPoster and BugSnag classes."""
|
|
103
103
|
return self.__configurator
|
|
104
104
|
|
|
105
|
-
def get_errors_count(self):
|
|
105
|
+
def get_errors_count(self) -> int:
|
|
106
106
|
"""Returns the number of exceptions reported."""
|
|
107
107
|
return self.__errors_count
|
|
108
108
|
|
|
109
109
|
def report_error(
|
|
110
110
|
self,
|
|
111
|
-
exception:
|
|
112
|
-
description:
|
|
113
|
-
metadata:
|
|
114
|
-
attachments:
|
|
115
|
-
assignee:
|
|
116
|
-
team:
|
|
117
|
-
group_by:
|
|
118
|
-
):
|
|
111
|
+
exception: Exception | None = None,
|
|
112
|
+
description: str | None = None,
|
|
113
|
+
metadata: dict | None = None,
|
|
114
|
+
attachments: list | None = None,
|
|
115
|
+
assignee: str | None = None,
|
|
116
|
+
team: str | None = None,
|
|
117
|
+
group_by: str | None = None,
|
|
118
|
+
) -> None:
|
|
119
119
|
"""Reports an error to the Jira project.
|
|
120
120
|
|
|
121
121
|
Args:
|
|
@@ -134,8 +134,13 @@ class BugCatcher:
|
|
|
134
134
|
logger.warning("Reporting an error is not supported in local environment.")
|
|
135
135
|
return
|
|
136
136
|
|
|
137
|
-
if
|
|
138
|
-
|
|
137
|
+
if (
|
|
138
|
+
not self.__configurator.is_jira_configured
|
|
139
|
+
and not self.__configurator.is_bugsnag_configured
|
|
140
|
+
):
|
|
141
|
+
logger.warning(
|
|
142
|
+
"Jira and BugSnag are not configured. Please configure them before reporting an error."
|
|
143
|
+
)
|
|
139
144
|
return
|
|
140
145
|
|
|
141
146
|
if not exception:
|
|
@@ -197,19 +202,21 @@ class BugCatcher:
|
|
|
197
202
|
)
|
|
198
203
|
|
|
199
204
|
frames = get_frames(exception.__traceback__)
|
|
200
|
-
exc_info =
|
|
205
|
+
exc_info = (
|
|
206
|
+
f"{Path(frames[-1].filename).name}:{frames[-1].name}:{frames[-1].lineno}"
|
|
207
|
+
)
|
|
201
208
|
exception.handled_error = exc_info
|
|
202
209
|
logger.info(f"Exception {exc_info} reported.")
|
|
203
210
|
self.__errors_count += 1
|
|
204
211
|
|
|
205
212
|
def report_error_to_jira(
|
|
206
213
|
self,
|
|
207
|
-
exception:
|
|
208
|
-
assignee:
|
|
209
|
-
attachments:
|
|
210
|
-
metadata:
|
|
211
|
-
additional_info:
|
|
212
|
-
):
|
|
214
|
+
exception: Exception | None = None,
|
|
215
|
+
assignee: str | None = None,
|
|
216
|
+
attachments: list | None = None,
|
|
217
|
+
metadata: dict | None = None,
|
|
218
|
+
additional_info: str | None = None,
|
|
219
|
+
) -> None:
|
|
213
220
|
"""Creates a Jira issue with the given attachments.
|
|
214
221
|
|
|
215
222
|
Args:
|
|
@@ -235,7 +242,9 @@ class BugCatcher:
|
|
|
235
242
|
metadata=metadata,
|
|
236
243
|
)
|
|
237
244
|
|
|
238
|
-
def report_error_to_bugsnag(
|
|
245
|
+
def report_error_to_bugsnag(
|
|
246
|
+
self, exception: Exception | None = None, metadata: dict | None = None
|
|
247
|
+
) -> None:
|
|
239
248
|
"""Sends an error to BugSnag.
|
|
240
249
|
|
|
241
250
|
Args:
|
|
@@ -271,7 +280,9 @@ class BugCatcher:
|
|
|
271
280
|
else:
|
|
272
281
|
exception.custom_attachments = [attachment]
|
|
273
282
|
|
|
274
|
-
def __excepthook(
|
|
283
|
+
def __excepthook(
|
|
284
|
+
self, exc_type: type, exc_value: Exception, exc_traceback: TracebackType
|
|
285
|
+
) -> None:
|
|
275
286
|
"""Handles unhandled exceptions.
|
|
276
287
|
|
|
277
288
|
Args:
|
|
@@ -286,8 +297,13 @@ class BugCatcher:
|
|
|
286
297
|
logger.warning("Reporting an error is not supported in local environment.")
|
|
287
298
|
return
|
|
288
299
|
|
|
289
|
-
if
|
|
290
|
-
|
|
300
|
+
if (
|
|
301
|
+
not self.__configurator.is_jira_configured
|
|
302
|
+
and not self.__configurator.is_bugsnag_configured
|
|
303
|
+
):
|
|
304
|
+
logger.warning(
|
|
305
|
+
"Jira and BugSnag are not configured. Please configure them before reporting an error."
|
|
306
|
+
)
|
|
291
307
|
return
|
|
292
308
|
|
|
293
309
|
handled_error = getattr(exc_value, "handled_error", None)
|
|
@@ -302,11 +318,13 @@ class BugCatcher:
|
|
|
302
318
|
if self.__configurator.is_bugsnag_configured:
|
|
303
319
|
self.__bug_snag.report_unhandled_error(exc_type, exc_value, exc_traceback)
|
|
304
320
|
frames = get_frames(exc_value.__traceback__)
|
|
305
|
-
exc_info =
|
|
321
|
+
exc_info = (
|
|
322
|
+
f"{Path(frames[-1].filename).name}:{frames[-1].name}:{frames[-1].lineno}"
|
|
323
|
+
)
|
|
306
324
|
logger.info(f"Exception {exc_info} reported.")
|
|
307
325
|
self.__errors_count += 1
|
|
308
326
|
|
|
309
|
-
def __get_sys_hook_attribute(self, attribute: str = "bug_catcher_client"):
|
|
327
|
+
def __get_sys_hook_attribute(self, attribute: str = "bug_catcher_client") -> None:
|
|
310
328
|
"""Checks if the system hook is installed.
|
|
311
329
|
|
|
312
330
|
Args:
|
|
@@ -317,14 +335,14 @@ class BugCatcher:
|
|
|
317
335
|
"""
|
|
318
336
|
return getattr(sys.excepthook, attribute, None)
|
|
319
337
|
|
|
320
|
-
def install_sys_hook(self):
|
|
338
|
+
def install_sys_hook(self) -> None:
|
|
321
339
|
"""Installs a system hook to handle unhandled exceptions."""
|
|
322
340
|
if self.__get_sys_hook_attribute():
|
|
323
341
|
return
|
|
324
342
|
|
|
325
343
|
self.__sys_excepthook = sys.excepthook
|
|
326
344
|
|
|
327
|
-
def excepthook(*exc_info):
|
|
345
|
+
def excepthook(*exc_info) -> None:
|
|
328
346
|
self.__excepthook(*exc_info)
|
|
329
347
|
|
|
330
348
|
if self.__sys_excepthook:
|
|
@@ -333,7 +351,7 @@ class BugCatcher:
|
|
|
333
351
|
sys.excepthook = excepthook
|
|
334
352
|
sys.excepthook.bug_catcher_client = self
|
|
335
353
|
|
|
336
|
-
def uninstall_sys_hook(self):
|
|
354
|
+
def uninstall_sys_hook(self) -> None:
|
|
337
355
|
"""Uninstalls the system hook to handle unhandled exceptions."""
|
|
338
356
|
client = self.__get_sys_hook_attribute()
|
|
339
357
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import bugsnag
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from .config import CONFIG
|
|
7
|
+
from .utils import logger
|
|
8
|
+
from .workitems import variables
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
bugsnag.configuration.auto_notify = False
|
|
12
|
+
|
|
13
|
+
# Default error message for BugSnag reports
|
|
14
|
+
_DEFAULT_ERROR_MESSAGE = "An error occurred during execution"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BugSnag:
|
|
18
|
+
"""BugSnag class for interacting with the BugSnag API."""
|
|
19
|
+
|
|
20
|
+
def __init__(self):
|
|
21
|
+
"""Initializes the BugSnag class."""
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def _create_generic_error(exception_type: type) -> Exception:
|
|
26
|
+
"""Creates a generic error of the given type with fallback handling.
|
|
27
|
+
|
|
28
|
+
Attempts to create an exception of the specified type with the default message.
|
|
29
|
+
If that fails, tries to create an empty exception of the same type.
|
|
30
|
+
If both fail, falls back to a generic Exception with the default message.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
exception_type (type): The type of exception to create.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Exception: An exception instance of the requested type (or Exception as fallback).
|
|
37
|
+
"""
|
|
38
|
+
# Try to create an exception of the same type with the default message
|
|
39
|
+
# If that fails, try with no arguments (empty exception)
|
|
40
|
+
# If both fail, fall back to using Exception
|
|
41
|
+
try:
|
|
42
|
+
error = exception_type(_DEFAULT_ERROR_MESSAGE)
|
|
43
|
+
except (TypeError, ValueError):
|
|
44
|
+
try:
|
|
45
|
+
# Try instantiating with no arguments (empty exception of same type)
|
|
46
|
+
error = exception_type()
|
|
47
|
+
except (TypeError, ValueError):
|
|
48
|
+
# Fall back to Exception if the custom exception type can't be instantiated
|
|
49
|
+
error = Exception(_DEFAULT_ERROR_MESSAGE)
|
|
50
|
+
return error
|
|
51
|
+
|
|
52
|
+
def config(self, api_key: str) -> bool:
|
|
53
|
+
"""Configures the BugSnag class.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
api_key (str): The API key for the BugSnag account.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
bool: True if the configuration was successful, False otherwise.
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
bugsnag.configure(
|
|
63
|
+
api_key=api_key, release_stage=CONFIG.ENVIRONMENT, auto_notify=False
|
|
64
|
+
)
|
|
65
|
+
run_id = os.environ.get("RC_PROCESS_RUN_ID", "unknown")
|
|
66
|
+
bugsnag.add_metadata_tab(
|
|
67
|
+
"Metadata",
|
|
68
|
+
{
|
|
69
|
+
"run_url": variables.get("processRunUrl", ""),
|
|
70
|
+
"run_by": variables.get("userEmail", ""),
|
|
71
|
+
"run_id": run_id,
|
|
72
|
+
},
|
|
73
|
+
)
|
|
74
|
+
response = requests.request(
|
|
75
|
+
"POST",
|
|
76
|
+
"https://otlp.bugsnag.com/v1/traces",
|
|
77
|
+
headers={
|
|
78
|
+
"Content-Type": "application/json",
|
|
79
|
+
"Bugsnag-Api-Key": api_key,
|
|
80
|
+
"Bugsnag-Payload-Version": "4",
|
|
81
|
+
"Bugsnag-Span-Sampling": "True",
|
|
82
|
+
},
|
|
83
|
+
data='{"message": "test"}',
|
|
84
|
+
timeout=None, # noqa: S113
|
|
85
|
+
)
|
|
86
|
+
if response.status_code not in [200, 201, 202, 204]:
|
|
87
|
+
logger.warning(f"Error connecting to Bugsnag: {response.text}")
|
|
88
|
+
return False
|
|
89
|
+
return True
|
|
90
|
+
except (requests.RequestException, ValueError, KeyError) as ex:
|
|
91
|
+
logger.warning(f"Failed to configure Bugsnag: {ex}")
|
|
92
|
+
return False
|
|
93
|
+
|
|
94
|
+
def report_error(
|
|
95
|
+
self, exception: Exception | None = None, metadata: dict | None = None
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Sends an error to BugSnag.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
exception (Exception, optional): The exception to report.
|
|
101
|
+
metadata (dict, optional): The metadata to be added to the Bugsnag issue. Defaults to None.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
None
|
|
105
|
+
"""
|
|
106
|
+
run_id = os.environ.get("RC_PROCESS_RUN_ID", "unknown")
|
|
107
|
+
# Use the same exception type as provided, or default to Exception
|
|
108
|
+
exception_type = type(exception) if exception is not None else Exception
|
|
109
|
+
error = self._create_generic_error(exception_type)
|
|
110
|
+
|
|
111
|
+
bugsnag.notify(
|
|
112
|
+
error,
|
|
113
|
+
metadata={"run_id": run_id},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def report_unhandled_error(self, exc_type, exc_value, traceback) -> None:
|
|
117
|
+
"""Sends an unhandled exception to BugSnag.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
exc_type (type): The type of the exception.
|
|
121
|
+
exc_value (Exception): The value of the exception.
|
|
122
|
+
traceback (traceback): The traceback of the exception.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
None
|
|
126
|
+
"""
|
|
127
|
+
run_id = os.environ.get("RC_PROCESS_RUN_ID", "unknown")
|
|
128
|
+
# Use the same exception type as provided, or default to Exception
|
|
129
|
+
exception_type = exc_type if exc_type is not None else Exception
|
|
130
|
+
error = self._create_generic_error(exception_type)
|
|
131
|
+
|
|
132
|
+
bugsnag.notify(
|
|
133
|
+
error,
|
|
134
|
+
metadata={"run_id": run_id},
|
|
135
|
+
severity="error",
|
|
136
|
+
)
|
|
@@ -64,10 +64,12 @@ class Config:
|
|
|
64
64
|
else variables.get("environment", "local")
|
|
65
65
|
)
|
|
66
66
|
|
|
67
|
-
STAGE = metadata.get("process",
|
|
68
|
-
ADMIN_CODE = metadata.get("process",
|
|
69
|
-
WORKER_NAME = metadata.get("process",
|
|
70
|
-
EMPOWER_URL = metadata.get("process",
|
|
67
|
+
STAGE = metadata.get("process", {}).get("implementationStage", "")
|
|
68
|
+
ADMIN_CODE = metadata.get("process", {}).get("adminCode", "")
|
|
69
|
+
WORKER_NAME = metadata.get("process", {}).get("name", "")
|
|
70
|
+
EMPOWER_URL = metadata.get("process", {}).get("processRunUrl") or variables.get(
|
|
71
|
+
"processRunUrl"
|
|
72
|
+
)
|
|
71
73
|
|
|
72
74
|
|
|
73
75
|
CONFIG = Config()
|