MCPcopy Index your code
hub / github.com/getsentry/sentry-javascript / createReduxEnhancer

Function createReduxEnhancer

packages/react/src/redux.ts:96–179  ·  view source on GitHub ↗

* Creates an enhancer that would be passed to Redux's createStore to log actions and the latest state to Sentry. * * @param enhancerOptions Options to pass to the enhancer

(enhancerOptions?: Partial<SentryEnhancerOptions>)

Source from the content-addressed store, hash-verified

94 * @param enhancerOptions Options to pass to the enhancer
95 */
96function createReduxEnhancer(enhancerOptions?: Partial<SentryEnhancerOptions>): any {
97 // Note: We return an any type as to not have type conflicts.
98 const options = {
99 ...defaultOptions,
100 ...enhancerOptions,
101 };
102
103 return (next: StoreEnhancerStoreCreator): StoreEnhancerStoreCreator =>
104 <S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, initialState?: PreloadedState<S>) => {
105 options.attachReduxState &&
106 getGlobalScope().addEventProcessor((event, hint) => {
107 try {
108 // @ts-expect-error try catch to reduce bundle size
109 if (event.type === undefined && event.contexts.state.state.type === 'redux') {
110 hint.attachments = [
111 ...(hint.attachments || []),
112 // @ts-expect-error try catch to reduce bundle size
113 { filename: 'redux_state.json', data: JSON.stringify(event.contexts.state.state.value) },
114 ];
115 }
116 } catch {
117 // empty
118 }
119 return event;
120 });
121
122 function sentryWrapReducer(reducer: Reducer<S, A>): Reducer<S, A> {
123 return (state, action): S => {
124 const newState = reducer(state, action);
125
126 const scope = getCurrentScope();
127
128 /* Action breadcrumbs */
129 const transformedAction = options.actionTransformer(action);
130 if (typeof transformedAction !== 'undefined' && transformedAction !== null) {
131 addBreadcrumb({
132 category: ACTION_BREADCRUMB_CATEGORY,
133 data: transformedAction,
134 type: ACTION_BREADCRUMB_TYPE,
135 });
136 }
137
138 /* Set latest state to scope */
139 const transformedState = options.stateTransformer(newState);
140 if (typeof transformedState !== 'undefined' && transformedState !== null) {
141 const client = getClient();
142 const options = client?.getOptions();
143 const normalizationDepth = options?.normalizeDepth || 3; // default state normalization depth to 3
144
145 // Set the normalization depth of the redux state to the configured `normalizeDepth` option or a sane number as a fallback
146 const newStateContext = { state: { type: 'redux', value: transformedState } };
147 setNormalizationDepthOverrideHint(
148 newStateContext,
149 3 + // 3 layers for `state.value.transformedState`
150 normalizationDepth, // rest for the actual state
151 );
152
153 scope.setContext('state', newStateContext);

Callers 1

redux.test.tsFile · 0.90

Calls 5

nextFunction · 0.85
sentryWrapReducerFunction · 0.85
addEventProcessorMethod · 0.80
getGlobalScopeFunction · 0.50
applyMethod · 0.45

Tested by

no test coverage detected