Hi,
I was wondering how to add a user context to something like
Async.each(users, (user, callback) => {
Sentry.configureScope((scope) => {
scope.setUser(user);
});
// Do something async for the user
// capture error for user in/after that async function
// Resulting user context will be the last user
}, callback);
I've tried creating a specific hub but that had the same issue
const userSpecificHub = new Sentry.Hub(Sentry.getCurrentHub().getClient());
userSpecificHub.run(() => {/* above example code here */})
Trying to do userSpecificHub.configureScope
to set the user resulted in the second hub/scope to have no user context.
I'm probably doing something wrong but I'm trying to add some context to some background processes (most of them get started by https://github.com/kelektiv/node-cron/)
Do you have access to the user throughout the whole life-span of that async function and you capture errors manually? Or do you want to rely on integrations?
If former, then it should be:
const users = [
{ id: 0 },
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 }
];
const processUser = user => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (user.id % 2 === 0) {
Sentry.withScope(scope => {
scope.setUser(user);
Sentry.captureException(new Error("whoops"));
});
}
resolve();
}, Math.random() * 1000);
});
};
Promise.all(users.map(processUser)).then(() => {
console.log("done");
});
However, if you want to have a separate hub for a whole life-span and modify it in various places, then this will work:
const users = [
{ id: 0 },
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 }
];
const processUser = user => {
return new Promise((resolve, reject) => {
const hub = new Sentry.Hub(Sentry.getCurrentHub().getClient());
hub.configureScope(scope => scope.setUser(user));
setTimeout(() => {
if (user.id % 2 === 0) {
hub.captureException(new Error("whoops"));
}
resolve();
}, Math.random() * 1000);
});
};
Promise.all(users.map(processUser)).then(() => {
console.log("done");
});
The second option seems what I want but couldn't get to work.
Is there a difference between using callbacks and promises? As that is the main difference I see with your example and my attempts :P
I will try again with your suggestion, thanks!
Is there a difference between using callbacks and promises?
As long as you dont do a for-loop and mess up your functions scope, then no, not at all :p
I'm not a 100% sure what you mean with don't do a for-loop
:/
for (var i = 0; i < 10; i++) {
// mimick async call
setTimeout(() => console.log(i))
}
This will print 10
ten times, and if you do it with hub
, it'll override it as well.
This will preserve correct scoping:
for (var i = 0; i < 10; i++) {
(function (x) {
// mimick async call
setTimeout(() => console.log(x))
})(i)
}
Oh I see, yeah that would be weird to do anyway :P we use Async for those operations :D
Closing as this seems to be solved.
Most helpful comment
Do you have access to the user throughout the whole life-span of that async function and you capture errors manually? Or do you want to rely on integrations?
If former, then it should be:
However, if you want to have a separate hub for a whole life-span and modify it in various places, then this will work: