You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Would there be a way to set a user directly on a transaction, instead of setting it using Scope.configure ?
For some reasons I am using a Sentry plugin with my graphQL implementation, but it seems that the user is not correctly set to my transactions (wrong user attached to the transaction of another user)
You'll find below the code of my plugin.
TLDR: I am creating my transaction first, then setting up the user as well as attaching the transaction as a span in Scope.configureScope. If I am doing something wrong, please let me know. I am expecting my transaction to have the correct user attached at that point but this is not the case.
const SentryPlugin: ApolloServerPlugin = {
async requestDidStart({ request, context }: GraphQLRequestContext) {
const sentryTransaction = Sentry.startTransaction({
op: 'gql',
name: request?.operationName || 'GraphQLTransaction'
});
const { user } = context;
if (user) {
Sentry.configureScope((scope) => {
scope.setUser({
id: user.uid,
email: user.email || null
});
scope.setSpan(sentryTransaction);
});
}
sentryTransaction.setData('query', request.query);
if (request.variables) {
sentryTransaction.setData('variables', JSON.stringify(request.variables));
}
if (request.http?.headers?.get('x-app-platform')) {
sentryTransaction.setTag('app-platform', request.http?.headers?.get('x-app-platform'));
}
if (request.http?.headers?.get('user-agent')) {
sentryTransaction.setTag('user-agent', request.http?.headers?.get('user-agent'));
}
if (request.http?.headers?.get('x-app-version')) {
sentryTransaction.setTag('app-version', request.http?.headers?.get('x-app-version'));
}
if (context.user?.appInfo?.userLocale) {
sentryTransaction.setTag('user-locale', context.user.appInfo.userLocale);
}
return {
async willSendResponse() {
sentryTransaction.finish();
},
async executionDidStart() {
return {
willResolveField({ info }) {
// hook for each new resolver
const span = sentryTransaction.startChild({
op: 'resolver',
description: `${info.parentType.name}.${info.fieldName}`
});
return () => {
// this will execute once the resolver is finished
span.finish();
};
}
};
},
async didEncounterErrors(ctx) {
// If we couldn't parse the operation, don't do anything here
if (!ctx.operation) {
return;
}
for (const err of ctx.errors) {
// Add scoped report details and send to Sentry
Sentry.withScope((scope) => {
// Annotate whether failing operation was query/mutation/subscription
scope.setTag('kind', ctx.operation?.operation || null);
scope.setTag('error-code', err.extensions?.code as string);
if (ctx.context.user?.teams && Array.isArray(ctx.context.user.teams) && context.user.teams.length) {
scope.setTag('user-teams', ctx.context.user.teams.map((t: TeamDocument) => t.id).join(','));
}
if (request.http?.headers?.get('x-app-platform')) {
scope.setTag('app-platform', request.http?.headers?.get('x-app-platform'));
}
if (request.http?.headers?.get('x-app-version')) {
scope.setTag('app-version', request.http?.headers?.get('x-app-version'));
}
if (err.path) {
// We can also add the path as breadcrumb
scope.addBreadcrumb({
category: 'query-path',
message: err.path.join(' > '),
level: 'debug'
});
}
scope.setSpan(sentryTransaction);
Sentry.captureException(err);
});
}
}
};
}
};
export default SentryPlugin;
Solution Brainstorm
Setting tags directly on the transaction object works well, can it be possible to also set the user directly on the transaction object ? This way we're sure to set the correct user on the correct transaction in the server lifecycle hook, and not on a global scope. I understand for a frontend that there will only be one user, but for the backend I'd like to have each different user for each of my transactions.
The text was updated successfully, but these errors were encountered:
At this point, it is not possible to set a user onto a transaction (or span) directly.
The could be a few reasons why the users are mixed up.
One of them might be that you're using configureScope which mutates the current scope instead of pushing a new scope onto the stack. Have you tried using Sentry.withScope instead and starting your transaction, setting the user and tags within the callback?
Another reason might be scope bleed because you're in an async (for instance, the transaction is finished in an async function). This is a known issue and unfortunately a hard problem to solve (see #4071). We'll work on replacing domains with AsyncLocalStorage in the future but for now there's little we can do about this.
Problem Statement
Would there be a way to set a user directly on a transaction, instead of setting it using Scope.configure ?
For some reasons I am using a Sentry plugin with my graphQL implementation, but it seems that the user is not correctly set to my transactions (wrong user attached to the transaction of another user)
You'll find below the code of my plugin.
TLDR: I am creating my transaction first, then setting up the user as well as attaching the transaction as a span in
Scope.configureScope
. If I am doing something wrong, please let me know. I am expecting my transaction to have the correct user attached at that point but this is not the case.Solution Brainstorm
Setting tags directly on the transaction object works well, can it be possible to also set the user directly on the transaction object ? This way we're sure to set the correct user on the correct transaction in the server lifecycle hook, and not on a global scope. I understand for a frontend that there will only be one user, but for the backend I'd like to have each different user for each of my transactions.
The text was updated successfully, but these errors were encountered: