You can track and monitor errors and exceptions in your code by capturing exception events. 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 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:
Name | Key | Example value |
---|---|---|
$exception_list | List | A list of exceptions that occurred. In languages that support chained exceptions, the list will contain multiple items. Contains the following properties: |
└─ type | String | The type of exception that occurred |
└─ value | String | The message of the exception that occurred |
└─ stacktrace | Object | Contains a list of stack frames that occurred |
└─ mechanism | Object | If the stacktrace is handled and if it's synthetic |
$exception_fingerprint | String | A fingerprint of the exception |
$exception_level | String | The level of the severity of the error |
Like normal events, it's important to identify the user when capturing exceptions.
If you serve minified or compiled code, PostHog needs source maps to display the correct stack traces. Configure source maps to get the most out of your exception events.
Automatic exception capture
If you followed one of our guides to set up error tracking and you enabled exception auto capture, you'll have automatic exception capture enabled.
posthog.init('<ph_project_api_key>', {api_host: '<ph_api_client_host>',defaults: '2025-05-24',capture_exceptions: {capture_unhandled_errors: true, // defaultcapture_unhandled_rejections: true, // defaultcapture_console_errors: false // default}})
Manual exception capture
You can also manually call the exception capture method.
posthog.captureException(error, {custom_property: "custom_value",custom_list: ["custom_value_1", "custom_value_2"],})
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, alerts, issue grouping. They can also be used in analysis in insights, dashboards, and data warehouse queries.
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 to group exceptions together at capture time.
Here are some examples of how to override exception properties:
try {// ...} catch (error) {posthog.captureException(error, {"custom_property": "custom_value",// You can also *optionally* override generated properties like fingerprint"$exception_fingerprint": "CustomExceptionGroup",});}
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 to group exceptions together at capture time.
The process is slightly different depending on the SDK you're using.
In JavaScript Web and Node.js SDKs, you can override the default properties by passing a before_send
callback. This callback is called before any exception is captured.
posthog.init('<ph_project_api_key>', {api_host:'https://us.i.posthog.com',defaults: '2025-05-24',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 fingerprintevent.properties["$exception_fingerprint"] = "MyCustomGroup"// ... and any other properties you want to override}}return event}})
Capturing properties for custom issue grouping rules
Other than grouping with custom fingerprints, you can also set custom properties on the exception to help you group exceptions together using issue grouping rules.
For example:
- Setting fields like
db_transaction
to group exceptions together for a specific database transactions. - Setting
feature_name
,service_name
, orservice_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 across multiple issues without grouping them.
Suppressing exceptions
We recommend that you suppress exceptions on the client side for performance and cost reasons.
You can use the before_send
callback in the web and Node.js SDKs to exclude any exception events you do not wish to capture. Do this by providing a before_send
function when initializing PostHog and have it return a falsey value for any events you want to drop.
posthog.init('<ph_project_api_key>', {before_send: (event) => {if (event.event === "$exception") {const exceptionList = event.properties["$exception_list"] || []const exception = exceptionList.length > 0 ? exceptionList[0] : null;if (exception && exception["$exception_type"] === "UnwantedError") {return false}}return event}})
You can also suppress exceptions in PostHog, these rules will be applied client-side.
Autocaptured exceptions can be ignored client-side by configuring suppression rules. Because the stack of an exception may still be minified client-side, you can only filter based on the exception type and message attributes.


Burst protection
The JavaScript web SDK uses burst protection to limit the number of autocaptured exceptions that can be captured in a period. This prevents an excessive amount of exceptions being captured from any one client, typically because they're being thrown in an infinite loop.
By default, we capture 10 exceptions (bucket size) of the same type within a 10 second period before the rate limiter kicks in, after which, we capture 1 exception (refill rate) every 10 seconds.
Often not needed, but you can change the bucket size and refill rate as part of your configuration:
import posthog from 'posthog-js'posthog.init('<ph_project_api_key>', {api_host: 'https://us.i.posthog.com',error_tracking: {__exceptionRateLimiterRefillRate: 1__exceptionRateLimiterBucketSize: 10}})