Skip to content

Commit c0013ef

Browse files
committed
feat: log captured exceptions
1 parent 18729e3 commit c0013ef

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 3.24.0 – 2025-04-10
2+
3+
1. Add config option to `log_captured_exceptions`
4+
15
## 3.23.0 – 2025-03-26
26

37
1. Expand automatic retries to include read errors (e.g. RemoteDisconnected)
@@ -203,7 +207,6 @@
203207

204208
1. Update type hints for module variables to work with newer versions of mypy
205209

206-
207210
## 3.3.3 - 2024-01-26
208211

209212
1. Remove new relative date operators, combine into regular date operators

posthog/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ def capture_exception(
314314
timestamp=None, # type: Optional[datetime.datetime]
315315
uuid=None, # type: Optional[str]
316316
groups=None, # type: Optional[Dict]
317+
**kwargs
317318
):
318319
# type: (...) -> Tuple[bool, dict]
319320
"""
@@ -327,6 +328,7 @@ def capture_exception(
327328
Optionally you can submit
328329
- `properties`, which can be a dict with any information you'd like to add
329330
- `groups`, which is a dict of group type -> group key mappings
331+
- remaining `kwargs` will be logged if `log_captured_exceptions` is enabled
330332
331333
For example:
332334
```python
@@ -355,6 +357,7 @@ def capture_exception(
355357
timestamp=timestamp,
356358
uuid=uuid,
357359
groups=groups,
360+
**kwargs
358361
)
359362

360363

posthog/client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def __init__(
126126
feature_flags_request_timeout_seconds=3,
127127
super_properties=None,
128128
enable_exception_autocapture=False,
129+
log_captured_exceptions=False,
129130
exception_autocapture_integrations=None,
130131
project_root=None,
131132
privacy_mode=False,
@@ -159,6 +160,7 @@ def __init__(
159160
self.historical_migration = historical_migration
160161
self.super_properties = super_properties
161162
self.enable_exception_autocapture = enable_exception_autocapture
163+
self.log_captured_exceptions = log_captured_exceptions
162164
self.exception_autocapture_integrations = exception_autocapture_integrations
163165
self.exception_capture = None
164166
self.privacy_mode = privacy_mode
@@ -513,6 +515,7 @@ def capture_exception(
513515
timestamp=None,
514516
uuid=None,
515517
groups=None,
518+
**kwargs
516519
):
517520
if context is not None:
518521
warnings.warn(
@@ -566,6 +569,9 @@ def capture_exception(
566569
**properties,
567570
}
568571

572+
if self.log_captured_exceptions:
573+
self.log.exception(exception, extra=kwargs)
574+
569575
return self.capture(distinct_id, "$exception", properties, context, timestamp, uuid, groups)
570576
except Exception as e:
571577
self.log.exception(f"Failed to capture exception: {e}")

posthog/test/test_client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ def test_basic_capture_exception_with_no_exception_happening(self):
263263
"WARNING:posthog:No exception information available",
264264
)
265265

266+
def test_capture_exception_logs_when_enabled(self):
267+
client = Client(FAKE_TEST_API_KEY, log_captured_exceptions=True)
268+
with self.assertLogs("posthog", level="ERROR") as logs:
269+
client.capture_exception(Exception("test exception"), "distinct_id", path="one/two/three")
270+
self.assertEqual(logs.output[0],"ERROR:posthog:test exception\nNoneType: None")
271+
self.assertEqual(getattr(logs.records[0], "path"),"one/two/three")
272+
266273
@mock.patch("posthog.client.decide")
267274
def test_basic_capture_with_feature_flags(self, patch_decide):
268275
patch_decide.return_value = {"featureFlags": {"beta-feature": "random-variant"}}

0 commit comments

Comments
 (0)