From 0133f21f4d855aef68673b2bdfbac01fd99f4113 Mon Sep 17 00:00:00 2001 From: Jenn Mueng <30991498+jennmueng@users.noreply.github.com> Date: Tue, 21 Jul 2020 20:47:58 +0700 Subject: [PATCH] feat: Docs for new Redux integration in @sentry/react (#1881) --- .../platforms/javascript/react.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/src/collections/_documentation/platforms/javascript/react.md b/src/collections/_documentation/platforms/javascript/react.md index 32f1ac8c3968c..9dfc87e6c65da 100644 --- a/src/collections/_documentation/platforms/javascript/react.md +++ b/src/collections/_documentation/platforms/javascript/react.md @@ -165,3 +165,134 @@ class App extends React.Component { 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. + + +```js +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`: + +```js +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: + +```js +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. + +```js +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. + +```js +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. + +```js +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); + } + } +}); +```