Closed as not planned
Description
Problem Statement
It is not possible for Sentry to always group errors correctly, as "correct" is subjective to the developer. If Sentry provides an option to enrich a thrown error object with a fingerprint, the developer is in full control over the fingerprint.
- Either Sentry groups to aggressively and groups errors that don't belong together -> Different errors (conceptually) that share the same stack trace.
- Conceptually the same errors that originate from different call stacks.
The current solutions has the following issues:
scope.setFingerprint
only works if the error is captured in the scope in which it occurs. If, instead, the error is thrown and caught in one central place, all scope information (and thus the fingerprint) is lost.beforeSend
adds needless complexity by requiring both copy-pasta setup code for every project, and at least one custom class that must also be copied alongside.
Solution Brainstorm
Imagine the following simplified code snippet:
export async function getThing() {
const res = await fetch('https://api.example.com/thing');
if (!res.ok) {
throw new Error(
`Failed to fetch the thing: ${res.status} ${res.statusText}.`,
{
cause: {
status: res.status,
statusText: res.statusText,
body: await res.text(),
},
},
);
}
try {
return await res.json();
} catch (err) {
throw new Error('Failed to fetch the thing: invalid JSON.', {
cause: {
body: await res.text(),
},
});
}
}
Any "Failed to fetch the thing: {status} {text}" error would be grouped as one issue by the same stack trace. There are several solutions to this:
Sentry.captureException
instead of throwing the error. This, however, is not always an option. If there is no logger instance available, there is no way to otherwise log the error, and depending on the project, the option return types this solution implies, don't always work.- Attach fingerprint to the error object:
Either with an error derivate that Sentry provides and attachesfingerprint
from a constructor parameter, or alternatively:
throw Object.assign(
new Error(`Failed to fetch the thing: ${res.status} ${res.statusText}.`, {
cause: {
status: res.status,
statusText: res.statusText,
body: await res.text(),
},
}),
{
fingerprint: ['fetch-thing-failed', res.status],
},
);
Then, the Sentry SDK would check for .fingerprint
properties on errors out of the box.
- Attach the scope to any thrown errors. The initial problem is that any errors thrown within a scope lose any context. This could be fixed with a
try-catch
withinSentry.withScope
that simply attaches itself to any errors it catches, so that any higher-level error handler still has access to the scope in which the error occurred. This would be the best solution in my opinion, as it also retains any other metadata set on the scope, such as tags and data, and makes those available to Sentry, as well as any other error logger, such as >stderr, which could then also benefit from scope data.
Metadata
Metadata
Assignees
Type
Projects
Status
No status