feat(prompts): add capture_errors option for error tracking#427
feat(prompts): add capture_errors option for error tracking#427andrewm4894 wants to merge 3 commits intomasterfrom
Conversation
…error tracking When capture_errors=True and a PostHog client is provided, prompt fetch failures are reported via client.capture_exception(). This surfaces prompt API errors in PostHog error tracking without affecting the existing fallback behavior (stale cache → fallback → raise).
posthog-python Compliance ReportDate: 2026-02-06 18:12:57 UTC
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 514ms |
| Format Validation.Event Has Uuid | ✅ | 1507ms |
| Format Validation.Event Has Lib Properties | ✅ | 1506ms |
| Format Validation.Distinct Id Is String | ✅ | 1505ms |
| Format Validation.Token Is Present | ✅ | 1506ms |
| Format Validation.Custom Properties Preserved | ✅ | 1506ms |
| Format Validation.Event Has Timestamp | ✅ | 1506ms |
| Retry Behavior.Retries On 503 | ✅ | 7799ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 3504ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 3507ms |
| Retry Behavior.Respects Retry After Header | ❌ | 7202ms |
| Retry Behavior.Implements Backoff | ❌ | 20574ms |
| Retry Behavior.Retries On 500 | ✅ | 7069ms |
| Retry Behavior.Retries On 502 | ✅ | 6630ms |
| Retry Behavior.Retries On 504 | ✅ | 7315ms |
| Retry Behavior.Max Retries Respected | ✅ | 20018ms |
| Deduplication.Generates Unique Uuids | ✅ | 1007ms |
| Deduplication.Preserves Uuid On Retry | ✅ | 7362ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ✅ | 12656ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ✅ | 6916ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 1501ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 1505ms |
| Compression.Sends Gzip When Enabled | ✅ | 1506ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 1506ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 1004ms |
| Batch Format.Multiple Events Batched Together | ✅ | 1504ms |
| Error Handling.Does Not Retry On 403 | ✅ | 3508ms |
| Error Handling.Does Not Retry On 413 | ✅ | 3505ms |
| Error Handling.Retries On 408 | ❌ | 6511ms |
Failures
retry_behavior.respects_retry_after_header
Retry delay too short: 693ms < 2500ms
retry_behavior.implements_backoff
First retry delay too short: 90ms < 100ms
error_handling.retries_on_408
Expected at least 2 requests, got 1
Radu-Raicea
left a comment
There was a problem hiding this comment.
Any way to support both instantiation methods?
| self._client = posthog if posthog is not None else None | ||
| self._capture_errors = capture_errors | ||
|
|
There was a problem hiding this comment.
Unchecked capture_exception call
_maybe_capture_error() assumes the provided posthog object has a capture_exception method. With capture_errors=True, passing a PostHog client version (or a stub) that lacks capture_exception will raise AttributeError, which then gets swallowed by the broad except Exception, meaning errors silently won’t be reported (and it’s hard to diagnose). Consider guarding the call (e.g., hasattr(self._client, "capture_exception")) and/or logging at least once at WARNING when the method is missing so users know why capture isn’t happening.
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/ai/prompts.py
Line: 97:99
Comment:
**Unchecked capture_exception call**
`_maybe_capture_error()` assumes the provided `posthog` object has a `capture_exception` method. With `capture_errors=True`, passing a PostHog client version (or a stub) that lacks `capture_exception` will raise `AttributeError`, which then gets swallowed by the broad `except Exception`, meaning errors silently won’t be reported (and it’s hard to diagnose). Consider guarding the call (e.g., `hasattr(self._client, "capture_exception")`) and/or logging at least once at WARNING when the method is missing so users know why capture isn’t happening.
How can I resolve this? If you propose a fix, please make it concise.| class TestPromptsCaptureErrors(TestPrompts): | ||
| """Tests for the capture_errors option.""" | ||
|
|
||
| @patch("posthog.ai.prompts._get_session") | ||
| def test_capture_exception_called_on_fetch_failure_with_fallback( |
There was a problem hiding this comment.
Tests are not parameterized
The new TestPromptsCaptureErrors cases are all the same shape (setup fetch failure/success → call get() → assert on capture_exception). This increases repetition and makes it easier to miss scenarios when adding new branches. The repo preference is parameterized tests; these can be collapsed into a single parameterized test that covers (fallback vs stale cache vs re-raise vs success) and toggles (capture_errors on/off, client present/absent).
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/test/ai/test_prompts.py
Line: 512:516
Comment:
**Tests are not parameterized**
The new `TestPromptsCaptureErrors` cases are all the same shape (setup fetch failure/success → call `get()` → assert on `capture_exception`). This increases repetition and makes it easier to miss scenarios when adding new branches. The repo preference is parameterized tests; these can be collapsed into a single parameterized test that covers (fallback vs stale cache vs re-raise vs success) and toggles (`capture_errors` on/off, client present/absent).
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
This is just an exploratory one. As a user i kinda might want posthog errors if we fail to handle prompt as expected. I dont think anything too crazy going on here but worth discussing.
Summary
capture_errorsparameter toPrompts.__init__()(defaultFalse, fully backward compatible)Trueand a PostHog client is provided, prompt fetch failures are reported viaclient.capture_exception()before the existing fallback logic runscapture_exception()itself fails, it is silently swallowed and never affects prompt resolutionMotivation
When using prompts with fallbacks, fetch failures are silently handled -- the caller gets a fallback string and the error is only logged at WARNING level. With
capture_errors=True, these failures surface in PostHog error tracking, making it easy to spot API issues, auth problems, or missing prompts without configuring Python logging.Usage
Changes
posthog/ai/prompts.py-- newcapture_errorsparam,_maybe_capture_error()helperposthog/test/ai/test_prompts.py-- 7 new tests covering all branchesTest plan