Files
posthog.com/contents/docs/error-tracking/capture.mdx
2025-09-16 19:00:34 +00:00

256 lines
9.1 KiB
Plaintext

---
title: Capture exceptions for error tracking
---
import Tab from "components/Tab"
You can track and monitor errors and exceptions in your code by capturing [exception events](/docs/error-tracking/issues-and-exceptions). This can be done automatically when exceptions are thrown in your code, or manually by calling the exception capture method.
## Capturing exceptions
Exceptions are a special type of [event](/docs/data/events) in PostHog. Similar to any other event, they can be captured, customized, filtered, and used in insights for analysis.
To help group exceptions into issues and help you debug them, PostHog automatically captures the following properties:
import ExceptionPropertiesTable from './_snippets/exception-properties-table.mdx'
<ExceptionPropertiesTable />
Like normal events, it's important to [identify the user](/docs/product-analytics/identify) when capturing exceptions.
import { CalloutBox } from 'components/Docs/CalloutBox'
<CalloutBox icon="IconInfo" title="Source maps" type="fyi">
If you serve minified or compiled code, PostHog needs source maps to display the correct stack traces. [Configure source maps](/docs/error-tracking/upload-source-maps) to get the most out of your exception events.
</CalloutBox>
### Automatic exception capture
If you followed one of our guides to [set up error tracking](/docs/error-tracking/installation) and you [enabled exception auto capture](https://app.posthog.com/error_tracking/configuration), you'll have automatic exception capture enabled.
```js
posthog.init('<ph_project_api_key>', {
api_host: '<ph_api_client_host>',
defaults: '<ph_posthog_js_defaults>',
capture_exceptions: {
capture_unhandled_errors: true, // default
capture_unhandled_rejections: true, // default
capture_console_errors: false // default
}
})
```
### Manual exception capture
You can also manually call the exception capture method.
<MultiLanguage>
```javascript file=Web
posthog.captureException(error, {
custom_property: "custom_value",
custom_list: ["custom_value_1", "custom_value_2"],
})
```
```javascript file=Node.js
posthog.captureException(e, 'user_distinct_id', {
custom_property: "custom_value",
custom_list: ["custom_value_1", "custom_value_2"],
})
```
```python
additional_properties = {
"custom_property": "custom_value",
"custom_list": ["custom_value_1", "custom_value_2"],
}
posthog.capture_exception(
e,
distinct_id="user_distinct_id",
properties=additional_properties
)
```
</MultiLanguage>
## Customizing exception capture
Like all data, the better **quality** of your exception events, the more **context** you'll have for debugging and analysis. Customizing exception capture helps you do this.
Customizing exception capture lets you override exception properties to influence how they're grouped into issues.
Equally important, you can customize properties on the exceptions to help you configure rules for [automatic issue assignment](/docs/error-tracking/assigning-issues#automatic-issue-assignment), [alerts](/docs/error-tracking/alerts), [issue grouping](/docs/error-tracking/grouping-issues). They can also be used in analysis in [insights](/docs/product-analytics/insights), [dashboards](/docs/product-analytics/dashboards), and [data warehouse queries](/docs/product-analytics/data-warehouse).
### Customizing exception properties
#### During manual capture
When capturing exceptions manually, passing properties to the capture exception method adds them to the event just like any other PostHog event.
You can also override the [fingerprint](/docs/error-tracking/fingerprints) to [group](/docs/error-tracking/issues-and-exceptions#how-are-issues-grouped) exceptions together at capture time.
Here are some examples of how to override exception properties:
<MultiLanguage>
```javascript file=Web
try {
// ...
} catch (error) {
posthog.captureException(error, {
"custom_property": "custom_value",
// You can also *optionally* override generated properties like fingerprint
"$exception_fingerprint": "CustomExceptionGroup",
});
}
```
```javascript file=Node.js
try {
// ...
} catch (error) {
posthog.captureException(error, 'user_123', {
"custom_property": "custom_value",
// You can also *optionally* override generated properties like fingerprint
"$exception_fingerprint": "CustomExceptionGroup",
});
}
```
```python
import posthog
posthog.api_key = '<ph_project_api_key>'
posthog.host = '<ph_client_api_host>'
# With context
with posthog.new_context():
posthog.identify_context(distinct_id="user_123")
# When using context, you define properties with tags
posthog.tag("custom_property", "custom_value")
# You can also *optionally* override generated properties like fingerprint
posthog.tag("$exception_fingerprint", ["custom_fingerprint"])
posthog.capture_exception(Exception("Test custom exception"))
# Or without context
posthog.capture_exception(
Exception("Test custom exception without context"),
distinct_id="user_123",
properties={
"$exception_type": "Custom exception without context",
"$exception_fingerprint": ["custom_fingerprint without context"],
"custom_property": "custom_value",
},
)
```
</MultiLanguage>
#### During automatic capture
When automatic exception capture is enabled, you can still override the default properties and add custom properties to the exception event.
You can also override the [fingerprint](/docs/error-tracking/fingerprints) to [group](/docs/error-tracking/issues-and-exceptions#how-are-issues-grouped) exceptions together at capture time.
The process is slightly different depending on the SDK you're using.
<Tab.Group tabs={['Web and Node.js', 'Python']}>
<Tab.List>
<Tab>Web and Node.js</Tab>
<Tab>Python</Tab>
</Tab.List>
<Tab.Panels>
<Tab.Panel>
In [JavaScript Web](/docs/libraries/js) and [Node.js](/docs/libraries/node) SDKs, you can override the default properties by passing a `before_send` callback. This callback is called before any exception is captured.
```javascript
posthog.init('<ph_project_api_key>', {
api_host:'<ph_client_api_host>',
defaults: '<ph_posthog_js_defaults>',
before_send: (event) => {
if (event && event.event === "$exception") {
const exceptionList = event.properties?.["$exception_list"] || []
const exception = exceptionList.length > 0 ? exceptionList[0] : null;
if (exception) {
event.properties["custom_property"] = "custom_value"
// You can also *optionally* override generated properties like fingerprint
event.properties["$exception_fingerprint"] = "MyCustomGroup"
// ... and any other properties you want to override
}
}
return event
}
})
```
</Tab.Panel>
<Tab.Panel>
In Python, you can override the default properties through the use of [contexts](/docs/libraries/python#contexts) and tags.
```python
import posthog
posthog.api_key = '<ph_project_api_key>'
posthog.host = '<ph_client_api_host>'
# With context
with posthog.new_context():
posthog.identify_context(distinct_id="<user_distinct_id>")
posthog.set_context_session(session_id="<session_id>")
posthog.tag("custom_property", "custom_value")
# You can also *optionally* override generated properties like fingerprint
posthog.tag("$exception_fingerprint", ["custom_fingerprint"])
# When this exception is automatically captured, it will be tagged with the custom properties
raise Exception("Test custom exception")
```
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
### Capturing properties for custom issue grouping rules
Other than grouping with [custom fingerprints](#customizing-exception-properties), you can also set custom properties on the exception to help you group exceptions together using [issue grouping rules](/docs/error-tracking/grouping-issues).
For example:
- Setting fields like `db_transaction` to group exceptions together for a specific database transactions.
- Setting `feature_name`, `service_name`, or `service_version` to group exceptions together for a specific features and services.
- Setting `intent` to group exceptions due to common interactions like accessing storage or network.
It's important to think about your grouping rules when you configure exception capture. You cannot group exceptions together if you don't set some common properties between them.
Note that grouping issues means that all exceptions will be grouped together under a **single issue**. You **cannot** group exceptions into multiple issues, but you can still [filter on custom properties](/docs/error-tracking/monitoring#finding-specific-issues) across multiple issues without grouping them.
## Suppressing exceptions
We recommend that you suppress exceptions on the client side for performance and cost reasons.
import BeforeSendHook from './_snippets/before-send-hook.mdx'
<BeforeSendHook />
You can also suppress exceptions in PostHog, these rules will be applied client-side.
import SuppressionRules from './_snippets/suppression-rules.mdx'
<SuppressionRules />
## Burst protection
import BurstProtection from './_snippets/burst-protection.mdx'
<BurstProtection />