Skip to content

Commit cf2f531

Browse files
authored
Merge pull request #94 from SEKOIA-IO/feat/send_exception_to_api
feat: Forward exceptions to the API
2 parents bfcae8a + be73266 commit cf2f531

File tree

3 files changed

+22
-14
lines changed

3 files changed

+22
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
### Added
1313

1414
- Add property to connector with `User-Agent` header to third party services
15+
- Forward exceptions to the API
1516

1617
## [1.6.2] - 2023-11-06
1718

sekoia_automation/trigger.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def _execute_once(self) -> None:
147147
# Configuration errors are considered to be critical
148148
except (TriggerConfigurationError, ModuleConfigurationError) as e:
149149
self.log_exception(e)
150-
self.log(str(e), "critical")
150+
self.log("Configuration error", "critical")
151151
except (ConnectionError, HTTPClientError) as ex:
152152
# Error while communicating with the S3 storage
153153
# Don't increment the error count because this is an internal issue
@@ -286,15 +286,19 @@ def send_event(
286286
remove_directory,
287287
)
288288

289-
# Try to send the log record to the API
290-
# If it can't be done, give up after 10 attempts and capture the logging error
289+
def log_exception(self, exception: Exception, **kwargs):
290+
super().log_exception(exception, **kwargs)
291+
# Send error to the API
292+
message = kwargs.get("message", "An exception occurred")
293+
self.log(f"{message}\n{exception}", level="error", propagate=False)
291294

292295
def log(self, message: str, level: str = "info", *args, **kwargs) -> None:
293296
if level == "critical" and self._critical_log_sent:
294297
# Prevent sending multiple critical errors
295298
level = "error"
296299

297-
super().log(message, level, *args, **kwargs)
300+
if kwargs.pop("propagate", True):
301+
super().log(message, level, *args, **kwargs)
298302

299303
self._logs.append(
300304
{
@@ -403,9 +407,6 @@ def _handle_trigger_exception(self, e: Exception):
403407
# Increase the consecutive error count
404408
self._error_count += 1
405409

406-
# Make sure the error is recorded and available to the user
407-
self.log(str(e), level="error")
408-
409410
# If there was more than 5 errors without any event being sent,
410411
# log a critical error.
411412
if self._is_error_critical():

tests/test_trigger.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def run(self):
135135

136136
trigger = TestTrigger()
137137

138-
with patch("sentry_sdk.capture_message") as sentry_patch:
138+
with patch("sentry_sdk.capture_exception") as sentry_patch:
139139
trigger._execute_once()
140140
sentry_patch.assert_called()
141141

@@ -365,9 +365,10 @@ def run(self):
365365
trigger.execute()
366366

367367
# configuration errors are directly considered to be critical
368-
assert mocked_trigger_logs.call_count == 1
368+
assert mocked_trigger_logs.call_count == 2
369+
assert mocked_trigger_logs.request_history[0].json()["logs"][0]["level"] == "error"
369370
assert (
370-
mocked_trigger_logs.request_history[0].json()["logs"][0]["level"] == "critical"
371+
mocked_trigger_logs.request_history[1].json()["logs"][0]["level"] == "critical"
371372
)
372373

373374

@@ -478,31 +479,34 @@ def test_trigger_liveness_not_found(monitored_trigger):
478479
assert res.status_code == 404
479480

480481

481-
def test_trigger_s3_connection_error():
482+
def test_trigger_s3_connection_error(mocked_trigger_logs):
482483
trigger = ErrorTrigger()
483484
trigger.ex = ConnectionError(error="Err")
484485

485486
with patch("sentry_sdk.capture_exception") as sentry_patch:
486487
trigger._execute_once()
487488
sentry_patch.assert_called()
489+
assert mocked_trigger_logs.called is True
488490
assert trigger._error_count == 0
489491

490492

491-
def test_trigger_s3_server_error_int():
493+
def test_trigger_s3_server_error_int(mocked_trigger_logs):
492494
trigger = ErrorTrigger()
493495
trigger.ex = ClientError({"Error": {"Code": 500}}, "foo")
494496
with patch("sentry_sdk.capture_exception") as sentry_patch:
495497
trigger._execute_once()
496498
sentry_patch.assert_called()
499+
assert mocked_trigger_logs.called is True
497500
assert trigger._error_count == 0
498501

499502

500-
def test_trigger_s3_server_error_str():
503+
def test_trigger_s3_server_error_str(mocked_trigger_logs):
501504
trigger = ErrorTrigger()
502505
trigger.ex = ClientError({"Error": {"Code": "ServiceUnavailable"}}, "foo")
503506
with patch("sentry_sdk.capture_exception") as sentry_patch:
504507
trigger._execute_once()
505508
sentry_patch.assert_called()
509+
assert mocked_trigger_logs.called is True
506510
assert trigger._error_count == 0
507511

508512

@@ -513,6 +517,7 @@ def test_trigger_s3_client_error_int(mocked_trigger_logs):
513517
trigger._execute_once()
514518
sentry_patch.assert_called()
515519
assert mocked_trigger_logs.called is True
520+
assert mocked_trigger_logs.call_count == 1
516521
assert trigger._error_count == 1
517522

518523

@@ -526,12 +531,13 @@ def test_trigger_s3_client_error_str(mocked_trigger_logs):
526531
assert trigger._error_count == 1
527532

528533

529-
def test_trigger_send_server_error():
534+
def test_trigger_send_server_error(mocked_trigger_logs):
530535
trigger = ErrorTrigger()
531536
trigger.ex = SendEventError("Server error", 500)
532537
with patch("sentry_sdk.capture_exception") as sentry_patch:
533538
trigger._execute_once()
534539
sentry_patch.assert_called()
540+
assert mocked_trigger_logs.called is True
535541
assert trigger._error_count == 0
536542

537543

0 commit comments

Comments
 (0)