Skip to content

Commit

Permalink
docs: add clarification about using Sentry's Error Boundary with the …
Browse files Browse the repository at this point in the history
…testkit
  • Loading branch information
zivl committed Nov 13, 2023
1 parent 03e352a commit e0d0508
Showing 1 changed file with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions website/docs/error-boundary-usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: Sentry/React Error Boundary
description: Explains how to use sentry-testkit with the Sentry/React Error Boundary
sidebar_position: 3
---

# Usage with `<Sentry.ErrorBoundary>`

The `@sentry/react` library exposes a `<Sentry.ErrorBoundary>` React component that can be used to catch errors in React components, similar to the `componentDidCatch` lifecycle method.

However, the `<Sentry.ErrorBoundary>` component causes Sentry to send multiple events due to the way it works under the hood. This is because it catches errors in the `componentDidCatch` lifecycle method, and then re-throws them, which causes Sentry to send another event. This is not a problem in production, but it can be a problem when testing.

## 3 Errors are sent to Sentry
When using `sentry-testkit` to test Sentry reports, the `testkit.reports()` call will return the following 3 total errors:

1. The original error that is captured by the error boundary
2. The original error captured by global event listener. This only occurs in in dev mode, because error boundaries rethrow the errors that they catch and those errors bubble up to the global event listener where it is captured again.
3. A synthetic react error boundary error that is generated by the sentry react sdk and attached to an error. This synthetic error is not captured as a standalone sentry event, but instead is included as part of the sentry event sent for the original error sent by the error boundary. See [Linked Errors](https://docs.sentry.io/platforms/javascript/guides/react/features/error-boundary/#linked-errors) for more details.

Internally, `sentry-testkit` uses the `testkit.reports()` call to find the report for the original error, so it will return the first error in the list above. This is the error that you should use to test your application.

:::info 2 Sentry events are being sent

Event A -> original error (1) + synthetic error boundary error (3)<br/>
Event B -> original error from global handlers (2)
:::



### Test Code Example

```javascript
import React from 'react'
import '@testing-library/jest-dom'
import { render } from '@testing-library/react'
import * as Sentry from '@sentry/react'
import sentryTestkit from 'sentry-testkit'

const { testkit, sentryTransport } = sentryTestkit()

const ThrowError = () => {
// eslint-disable-next-line
throw Error('test error')
}

describe('Inside ErrorBoundary', () => {
const consoleError = console.error
beforeAll(() => {
console.error = jest.fn()
Sentry.init({
dsn: 'https://[email protected]/000001',
transport: sentryTransport,
})
})
afterAll(() => {
console.error = consoleError
})

test('should render fallback component and captureException when error is thrown', async () => {
expect(testkit.reports()).toHaveLength(0)
render(
<Sentry.ErrorBoundary fallback={<div>some error</div>}>
<ThrowError />
</Sentry.ErrorBoundary>
)
expect(testkit.reports()).toHaveLength(3)
})
})
```

## What Else Can Be Done About It?
You can alway customize it through Sentry's Integrations mechanism.

For example, you can disable the `GlobalHandler` Integration by doing the following:

```javascript
import * as Sentry from '@sentry/react'
import { Integrations } from '@sentry/tracing'

Sentry.init({
// ...
integrations: function (integrations) {
return integrations.filter(function (integration) {
return integration.name !== "GlobalHandlers";
});
},
});

```

You can also take a look on the `CaptureConsole` Integration, which is responsible for capturing console errors. You can disable it by doing the following:

```javascript
import * as Sentry from '@sentry/react'
import { Integrations } from '@sentry/tracing'

Sentry.init({
// ...
integrations: function (integrations) {
return integrations.filter(function (integration) {
return integration.name !== "CaptureConsole";
});
},
});
```

:::info
Find more information about Sentry's Integrations [here](https://docs.sentry.io/platforms/javascript/configuration/integrations).
:::

0 comments on commit e0d0508

Please sign in to comment.