Skip to content

Add filterBreadcrumbActions option #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ This library makes, what I think are, a few improvements over
`<script>` tag.
2. Adds your state and last action as context to _all_ errors, not just reducer
exceptions.
3. Allows filtering action breadcrumbs before sending to Sentry

## API: `createRavenMiddleware(Raven, [options])`

Expand Down Expand Up @@ -128,6 +129,16 @@ Each breadcrumb is assigned a category. By default all action breadcrumbs are
given the category `"redux-action"`. If you would prefer a different category
name, specify it here.

#### `filterBreadcrumbActions` _(Function)_
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might also be worth adding to the "improvements" section above.


Default: `action => true` _(Function)_

If your app has certain actions that you do not want to send to Sentry, pass
a filter function in this option. If the filter returns a truthy value, the
action will be added as a breadcrumb, otherwise the action will be ignored.
Note: even when the action has been filtered out, it may still be sent to
Sentry as part of the extra data, if it was the last action before an error.

## Changelog

### 1.0.0
Expand Down
16 changes: 10 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const identity = x => x;
const getUndefined = () => {};
const filter = () => true;
function createRavenMiddleware(Raven, options = {}) {
// TODO: Validate options.
const {
breadcrumbDataFromAction = getUndefined,
actionTransformer = identity,
stateTransformer = identity,
breadcrumbCategory = "redux-action"
breadcrumbCategory = "redux-action",
filterBreadcrumbActions = filter
} = options;

return store => {
Expand All @@ -21,11 +23,13 @@ function createRavenMiddleware(Raven, options = {}) {
return next => action => {
// Log the action taken to Raven so that we have narrative context in our
// error report.
Raven.captureBreadcrumb({
category: breadcrumbCategory,
message: action.type,
data: breadcrumbDataFromAction(action)
});
if (filterBreadcrumbActions(action)) {
Raven.captureBreadcrumb({
category: breadcrumbCategory,
message: action.type,
data: breadcrumbDataFromAction(action)
});
}

lastAction = action;
return next(action);
Expand Down
42 changes: 41 additions & 1 deletion index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,18 @@ describe("raven-for-redux", function() {
context.breadcrumbDataFromAction = jest.fn(action => ({
extra: action.extra
}));
context.filterBreadcrumbActions = action => {
return action.type !== "UNINTERESTING_ACTION";
};

context.store = createStore(
reducer,
applyMiddleware(
createRavenMiddleware(Raven, {
stateTransformer: context.stateTransformer,
actionTransformer: context.actionTransformer,
breadcrumbDataFromAction: context.breadcrumbDataFromAction
breadcrumbDataFromAction: context.breadcrumbDataFromAction,
filterBreadcrumbActions: context.filterBreadcrumbActions
})
)
);
Expand Down Expand Up @@ -178,4 +182,40 @@ describe("raven-for-redux", function() {
);
});
});

describe("with filterBreadcrumbActions option enabled", function() {
beforeEach(function() {
context.filterBreadcrumbActions = action => {
return action.type !== "UNINTERESTING_ACTION";
};

context.store = createStore(
reducer,
applyMiddleware(
createRavenMiddleware(Raven, {
filterBreadcrumbActions: context.filterBreadcrumbActions
})
)
);
});
it("filters actions for breadcrumbs", function() {
context.store.dispatch({ type: "INCREMENT" });
context.store.dispatch({ type: "UNINTERESTING_ACTION" });
context.store.dispatch({ type: "UNINTERESTING_ACTION" });
Raven.captureMessage("report!");

expect(context.mockTransport).toHaveBeenCalledTimes(1);
const { breadcrumbs } = context.mockTransport.mock.calls[0][0].data;
expect(breadcrumbs.values.length).toBe(1);
});
it("sends action with data.extra even if it was filtered", function() {
context.store.dispatch({ type: "UNINTERESTING_ACTION" });
Raven.captureMessage("report!");

expect(context.mockTransport).toHaveBeenCalledTimes(1);
const { extra } = context.mockTransport.mock.calls[0][0].data;
// Even though the action isn't added to breadcrumbs, it should be sent with extra data
expect(extra.lastAction).toEqual({ type: "UNINTERESTING_ACTION" });
});
});
});