Skip to content

Latest commit

 

History

History
279 lines (211 loc) · 9.66 KB

File metadata and controls

279 lines (211 loc) · 9.66 KB
title sidebar_order keywords
React
30
reactjs

To use Sentry with your React application, you will need to use @sentry/react (Sentry’s Browser React SDK).

{% capture __alert_content -%} @sentry/react is a wrapper around the @sentry/browser package, with added functionality related to React. All methods available in the @sentry/browser package can also be imported from @sentry/react. {%- endcapture -%} {%- include components/alert.html title="Note" content=__alert_content level="info" %}

{% include_relative getting-started-install/react.md %}

Connecting the SDK to Sentry

After you've completed setting up a project in Sentry, Sentry will give you a value which we call a DSN or Data Source Name. It looks a lot like a standard URL, but it’s just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier.

{% include_relative getting-started-dsn/react.md %}

On its own, @sentry/react will report any uncaught exceptions triggered by your application.

You can trigger your first event from your development environment by raising an exception somewhere within your application. An example of this would be rendering a button:

return <button onClick={methodDoesNotExist}>Break the world</button>;

Error Boundaries

If you're using React 16 or above, Error Boundaries are an essential tool for defining your application's behavior in the face of errors. The @sentry/react package exposes an error boundary component that automatically sends JavaScript errors from inside a React component tree to Sentry.

{% capture __alert_content -%} In development mode, React will rethrow errors caught within an error boundary. This will result in errors being reported twice to Sentry with the above setup, but this won’t occur in your production build. {%- endcapture -%} {%- include components/alert.html title="Note" content=__alert_content level="warning" %}

In the example below, when the <Example /> component hits an error, the <Sentry.ErrorBoundary> component will send data about that error and the component tree to Sentry, open a user feedback dialog, and render a fallback UI.

import React from 'react';
import * as Sentry from '@sentry/react';

import {Example} from '../example';

function FallbackComponent() {
  return (
    <div>An error has occured</div>
  )
}

class App extends React.Component {
  render() {
    return (
      <Sentry.ErrorBoundary fallback={FallbackComponent} showDialog>
        <Example />
      </Sentry.ErrorBoundary>
    )
  }
}

export default App;

ErrorBoundary Options

The ErrorBoundary component exposes a variety of props that can be passed in for extra configuration. There are no required options, but we highly recommend that you set a fallback component.

showDialog (boolean)

If a [Sentry User Feedback Widget]({%- link _documentation/enriching-error-data/user-feedback.md -%}?platform={{ include.platform }}) should be rendered when the Error Boundary catches an error.

dialogOptions (Object)

Options that are passed into the Sentry User Feedback Widget. See all possible customization options [here]({%- link _documentation/enriching-error-data/user-feedback.md -%}?platform={{ include.platform }}#customizing-the-widget)

fallback (React.ReactNode or Function)

A fallback component that gets rendered when the error boundary encounters an error. You can can either provide a React Component, or a function that returns a React Component as a valid fallback prop. If you provide a function, Sentry will call the function with the error and the component stack at the time of the error.

onError (Function)

A function that gets called when the Error Boundary encounters an error. onError is useful if you want to propagate the error into a state management library like Redux, or if you want to check any side effects that could have occurred due to the error.

onMount (Function)

A function that gets called on ErrorBoundary componentDidMount()

onUnmount (Function)

A function that gets called on ErrorBoundary componentWillUnmount()

ErrorBoundary Usage

Setting a Fallback Function (Render Props)

Below is an example where a fallback prop, using the render props approach, is used to display a fallback UI on error, and gracefully return to a standard component state when reset.

import React from 'react';
import * as Sentry from '@sentry/react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: "This is my app",
    };
  }

  render() {
    return (
      <Sentry.ErrorBoundary fallback={({ error, componentStack, resetError }) => (
          <React.Fragment>
            <div>You have encountered an error</div>
            <div>{error.toString()}</div>
            <div>{componentStack}</div>
            <button
              onClick={() => {
                this.setState({ message: "This is my app" });
                resetError();
              }}
            >
              Click here to reset!
            </button>
          </React.Fragment>
        )}>
        <div>{this.state.message}</div>
        {/* on click, this button sets an Object as a message, not a string. */}
        {/* which will cause an error to occur in the component tree */}
        <button onClick={() => this.setState({ message: {text: "Hello World"} })}>Click here to change message!</button>
      </Sentry.ErrorBoundary>
    )
  }
}

export default App;

Redux

{% version_added 5.20.0 %}

Redux support is included in the @sentry/react package since version 5.20.0. To apply Sentry to Redux, use Sentry.createReduxEnhancer at the same place that you initialize your Redux store.

import { createStore, compose } from 'redux';
import * as Sentry from '@sentry/react'

// ...

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  // Optionally pass options listed below
});

const store = createStore(rootReducer, sentryReduxEnhancer);

// ...

If you have other enhancers or middleware such as thunk:

const store = createStore(rootReducer, compose(applyMiddleware(thunk), sentryReduxEnhancer));

{% capture __alert_content -%} Sentry uses a redux enhancer. Pass the enhancer, as indicated above. Don't pass it to applyMiddleware and don't call the method when you pass it to the createStore method. {%- endcapture -%} {%- include components/alert.html title="Note" content=__alert_content level="info" %}

Normalization Depth

By default Sentry SDKs normalize any context to a depth of 3, which in the case of sending Redux state you probably will want to increase that. You do so by passing normalizeDepth to the Sentry.init call:

Sentry.init({
  dsn: '___DSN___',
  normalizeDepth: 10 // Or however deep you want your state context to be.
})

Redux Enhancer Options

Pass an options object as the first parameter to Sentry.createReduxEnhancer to configure it.

{% capture __alert_content -%} We advise against sending sensitive information to Sentry, but if you do, we will try our best to filter out things such as user passwords. {%- endcapture -%} {%- include components/alert.html title="Note" content=__alert_content level="warning" %}

actionTransformer (Function)

Used to remove sensitive information from actions. The first parameter passed to the function is the Redux action. Return null to not send the action to Sentry. By default we send all actions.

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  actionTransformer: action => {
    if (action.type === "GOVERNMENT_SECRETS") {
      // Return null to not log the action to Sentry
      return null;
    }
    if (action.type === "SET_PASSWORD" ) {
      // Return a transformed action to remove sensitive information
      return {
        ...action,
        password: null
      }
    };
    
    return action;
  }
});

stateTransformer (Function)

Used to remove sensitive information from state. The first parameter passed to the function is the Redux state. Return null to not attach the state to events sent to Sentry. Note that if you choose not to send state to Sentry, your errors might not have the latest version of the state attached. By default, we attach all state changes.

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  stateTransformer: state => {
    if (state.topSecret.doNotSend) {
      // Return null to not send this version of the state.
      return null;
    }
    
    // Transform the state to remove sensitive information
    const transformedState = {
      ...state,
      topSecret: {
        ...state.topSecret,
        // Replace sensitive information with something else
        nuclearLaunchCodes: "I love pizza",
        // or just remove it entirely
        hiddenTreasureLocation: null
      },
      // You should also remove large data that is irrelevant to debugging to not clutter your Sentry issues
      giganticState: null
    };
    
    return transformedState;
  }
})

configureScopeWithState (Function)

Called on every state update, configure the Sentry Scope with the Redux state. The first parameter is the scope, which is the same scope instance that you would get when you call Sentry.configureScope, and the second parameter is the latest Redux state.

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  configureScopeWithState: (scope, state) => {
    // Set tag if the user is using imperial units.
    if (state.settings.useImperialUnits) {
      scope.setTag('user.usesImperialUnits', true);
    }
  }
});