Sentry Raven Middleware for Redux

raw JSON →
1.4.0 verified Thu Apr 23 auth: no javascript deprecated

raven-for-redux is a Redux middleware designed to integrate Redux state and actions with Sentry's error tracking platform through the legacy raven-js client. It intercepts dispatched actions, logging their types as breadcrumbs and attaching the last action and current Redux state as additional context to all errors, not just reducer exceptions. As of version 1.4.0, it requires raven-js version 3.9.0 or higher, with a known bug triggered by raven-js 3.14.0. The library differentiates itself by allowing the Sentry Raven client to be injected, providing flexible configuration, and offering options to filter action breadcrumbs and define user context mappings from the Redux state. Its release cadence has been infrequent, and its primary dependency, raven-js, is officially deprecated in favor of `@sentry/browser`, making this package suitable only for projects using older Sentry integrations.

error TypeError: Cannot read properties of undefined (reading 'config') at createRavenMiddleware
cause The `Raven` object was not correctly initialized or passed as the first argument to `createRavenMiddleware`.
fix
Ensure Raven.config('<YOUR_DSN>').install(); is called and completes successfully before creating the middleware, and that the initialized Raven object is passed as the first argument to createRavenMiddleware.
error Sentry: Breadcrumbs or errors are not being reported, or are malformed in Sentry dashboard.
cause This symptom commonly occurs if `raven-js` version 3.14.0 is being used, which has a known bug impacting `raven-for-redux`.
fix
Downgrade your raven-js dependency to a version other than 3.14.0, or preferably, migrate your Sentry integration to the actively maintained @sentry/browser package.
error Actions appear in Sentry breadcrumbs without expected modifications from other middlewares, or the attached state context is incorrect/stale.
cause The `raven-for-redux` middleware is likely placed too early in the Redux `applyMiddleware` chain, causing it to capture state or actions before other middlewares have processed them.
fix
Reorder your middlewares so that createRavenMiddleware is placed after any other middlewares that modify actions or state (e.g., redux-thunk, redux-promise, redux-saga).
breaking The underlying Sentry client, `raven-js`, is officially deprecated by Sentry. New projects should migrate to `@sentry/browser` and `@sentry/redux` for modern Sentry integration.
fix Consider migrating your Sentry integration to the `@sentry/browser` and `@sentry/redux` packages for continued support and new features. This package will not work with modern Sentry SDKs.
gotcha A specific bug exists in `raven-js` version 3.14.0 that can be triggered by `raven-for-redux`, potentially preventing breadcrumbs or errors from being reported correctly.
fix Avoid using `raven-js` version 3.14.0. Downgrade to an earlier 3.x version or upgrade to a later version if available and compatible. The best long-term solution is to migrate to `@sentry/browser`.
gotcha `raven-for-redux` middleware should be placed *after* other Redux middlewares (like `redux-thunk` or `redux-promise`) that might intercept, transform, or emit new actions. Incorrect placement can lead to actions not being logged or incorrect state being attached.
fix Ensure `createRavenMiddleware` is the last middleware applied in your `applyMiddleware` chain if other middlewares modify or generate actions.
gotcha The `breadcrumbDataFromAction` option, while powerful, should be used with caution. Logging large or sensitive portions of the action object or state can negatively impact performance and Sentry event size limits.
fix Be selective about the data returned by `breadcrumbDataFromAction`, including only necessary, non-sensitive, and small pieces of information to avoid performance issues and Sentry data caps.
gotcha When using TypeScript with `raven-for-redux`'s DefinitelyTyped bindings, the import style for `createRavenMiddleware` differs from typical ES module default imports.
fix Use `import * as createRavenMiddleware from 'raven-for-redux';` instead of `import createRavenMiddleware from 'raven-for-redux';` in TypeScript files to correctly utilize the provided typings.
npm install raven-for-redux
yarn add raven-for-redux
pnpm add raven-for-redux

This example demonstrates how to integrate `raven-for-redux` with a Redux store, capturing actions as Sentry breadcrumbs and attaching state context to errors. It includes a mock reducer, Raven initialization, and an example of error capturing with custom options.

import Raven from "raven-js";
import { createStore, applyMiddleware, combineReducers } from "redux";
import createRavenMiddleware from "raven-for-redux";

// Mock reducer for demonstration
const initialState = { count: 0, user: { id: 1, name: 'Guest' } };
function reducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'LOGIN':
      return { ...state, user: action.payload };
    default:
      return state;
  }
}

// Initialize Raven (or mock it for local development without a DSN)
const SENTRY_DSN = process.env.SENTRY_DSN ?? "https://examplePublicKey@o0.ingest.sentry.io/0";
// In a real application, you would always provide a valid DSN.
Raven.config(SENTRY_DSN).install();

const store = createStore(
    reducer,
    applyMiddleware(
        // Middlewares that intercept or emit actions should generally precede raven-for-redux.
        createRavenMiddleware(Raven, {
            breadcrumbMessageFromAction: action => action.type,
            breadcrumbDataFromAction: action => ({ actionPayload: action.payload }),
            stateContext: state => ({ user: state.user }),
            actionFilter: action => action.type !== 'IGNORE_THIS_ACTION'
        })
    )
);

// Dispatch some actions to generate breadcrumbs
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'LOGIN', payload: { id: 123, name: 'Alice' } });
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'IGNORE_THIS_ACTION' }); // This action will be filtered out

// Simulate an error to capture state and breadcrumbs
try {
  throw new Error("Simulated error during user interaction!");
} catch (e) {
  Raven.captureException(e);
}

console.log('Final State:', store.getState());
// In a real app, console.logs would typically be replaced by actual Sentry reports.