Closed pkuczynski closed 4 years ago
See #82.
Have seen this and finally implemented this integration myself, dropping usage of this package
@pkuczynski care to share how you did it?
+1 @pkuczynski if you can show us something around this !
Sure!
I created a new file in src/store/middlewares/sentry.js
:
import * as Sentry from '@sentry/browser'
const sentry = (store) => {
Sentry.configureScope((scope) => {
scope.addEventProcessor((event) => {
// line below assumes that username is stores under user in the state
const { user: { username }, ...state } = store.getState()
return {
...event,
extra: {
...event.extra,
'redux:state': state
},
user: {
...event.user,
username
}
}
})
})
return next => (action) => {
Sentry.addBreadcrumb({
category: 'redux-action',
message: action.type
})
return next(action)
}
}
export default sentry
then I also had one place where I define all my middlewares src/store/middlewares/sentry.js
:
import { applyMiddleware } from 'redux'
...
import sentry from './sentry'
const middlewares = applyMiddleware(
...
sentry
)
export default middlewares
and then in a place where I initialize store I had:
const store = createStore(
reducers,
compose(middlewares)
)
For anyone coming across @pkuczynski's awesome comment in the future:
If you can't seem to get redux:state
to show up when capturing an exception using withScope
later on in your app, you probably want to use addGlobalEventProcessor
.
- Sentry.configureScope((scope) => {
- scope.addEventProcessor((event) => {
+ Sentry.addGlobalEventProcessor((event) => {
@pkuczynski Your suggested code seems to be the way forward! Have you thought about wrapping it up into a separate package? :-D
@OliverJAsh I could if you promise to use it ;)
Haha, I promise! That plus 27 other ❤️s!
Not sure if this works 100% like the current raven-for-redux
but I tried to work based on the current implementation. I tested on the example and apparently it did ok... But I didn't refactor the tests to check.
const identity = x => x;
const getUndefined = () => {};
const getType = action => action.type;
const filter = () => true;
function createSentryMiddleware(Sentry, options = {}) {
// TODO: Validate options.
const {
breadcrumbDataFromAction = getUndefined,
breadcrumbMessageFromAction = getType,
actionTransformer = identity,
stateTransformer = identity,
breadcrumbCategory = "redux-action",
filterBreadcrumbActions = filter,
getUserContext,
getTags
} = options;
let lastAction;
return store => {
Sentry.configureScope((scope) => {
scope.addEventProcessor((event) => {
const state = store.getState();
const user = getUserContext
? Object.assign({}, event.user, getUserContext(state))
: event.user;
const tag = getTags
? Object.assign({}, event.tag, getTags(state))
: event.tag;
const extra = Object.assign({}, event.extra, {
state: stateTransformer(state),
lastAction: actionTransformer(lastAction),
});
return Object.assign({}, event, { extra, user, tag });
});
});
return next => action => {
// Log the action taken to Sentry so that we have narrative context in our
// error report.
if (filterBreadcrumbActions(action)) {
Sentry.addBreadcrumb({
category: breadcrumbCategory,
message: breadcrumbMessageFromAction(action),
data: breadcrumbDataFromAction(action)
});
}
lastAction = action;
return next(action);
};
}
}
module.exports = createSentryMiddleware;
For reference, the above implementation using the scope.addEventProcessor
method gets called when sentry is about to send the error and not when the error is thrown. Since Redux keeps on working, you end up getting misleading information as there are breadcrumbs (i.e. actions) which were emitted after the exception was thrown.
To avoid this, you can store the state, action and breadcrumbs from when the Sentry.lastEventId()
is changed (which means an error was thrown) and then using this stored data to modify the scope using addEventProcessor
.
You can check out this gist: https://gist.github.com/olavoasantos/9ac791098758ee7dedf0c0424ec8b398
This claims to be a rewrite of raven-for-redux
with support for @sentry/browser
: https://github.com/vidit-sh/redux-sentry-middleware
I haven't tried it yet 🤞
This claims to be a rewrite of
raven-for-redux
with support for@sentry/browser
: https://github.com/vidit-sh/redux-sentry-middlewareI haven't tried it yet 🤞
I tried it briefly and it seems to be working properly! 🎉
Yep, I can confirm that it is working well using @sentry/browser
@ 5.7.0
https://github.com/vidit-sh/redux-sentry-middleware looks like the right approach. I'll update the readme to point people there.
@sentry/browser
is the latest version of Sentry SDK. I tried to upgrade my project, but my application fails to run with an errorRaven.setDataCallback is not a function
. That's because the Sentry API changed significantly and this library would have to be updated...