Only report errors you will actually fix.
If an error shows up in Sentry and nobody's going to do anything about it, it shouldn't be there. Everything below applies this principle to common scenarios.
What to Report
Yes — send to Sentry:
- Unhandled exceptions in your code
- Database connection failures
- Third-party API failures
- Failed queue jobs
- Anything that returns a 500 (on the backend)
No — filter out:
- Validation errors (422)
- Authentication failures (401)
- Authorization errors (403)
- Not found (404)
- Rate limiting (429)
- HTTP errors caught on the frontend
- Generic network failures
The Three Rules
1. Expected responses are not bugs.
Validation, auth, and 404 errors mean your app is working correctly. A user typing asdf into an email field isn't a bug you need to fix.
2. Report server errors on the backend, not the frontend.
When your server returns a 500, it reports to Sentry with the full stack trace. If your frontend also reports "API returned 500", you get a useless issue with no context. The backend already told you what went wrong.
3. Not all network errors are equal.
A user's flaky WiFi isn't your problem. But CORS errors, SSL issues, or JSON parse failures are bugs you need to fix.
Filter if the error just says "network bad." Keep if it points to something specific.
Backend Setup
Configure your error handler to ignore exceptions that aren't bugs. Every framework has a way to exclude exception types from reporting—use it for:
- Validation exceptions
- Authentication exceptions
- Authorization exceptions
- Not found exceptions
- Rate limit exceptions
Frontend Setup
Sentry.init({
dsn: 'your-dsn',
ignoreErrors: [
/ResizeObserver loop/, // Browser quirk, harmless
'Non-Error promise rejection',
],
// Ignore errors originating from extensions
denyUrls: [
/extensions\//i,
/^chrome-extension:\/\//i,
/^moz-extension:\/\//i,
],
beforeSend(event, hint) {
if (hint.originalException?.name === 'AbortError') return null;
return event;
},
});
Be careful about these ones though 👇
You may see advice to blanket-ignore Failed to fetch, Loading chunk failed, NetworkError, Script error. Be careful:
Failed to fetchcan indicate CORS misconfigurationsLoading chunk failedoften means your deployment deleted old chunks while users still have cached HTML pointing to them — that's a deployment bug, not user errorScript errorcan hide real issues in third-party scripts you depend on
Monitor volume before ignoring. If you see spikes, investigate. Only filter after you're confident they're not actionable.
API Client Setup
Don't sprinkle Sentry.captureException() in your API error handling. The backend already reported 5xx errors with full context. Just handle the UX and let errors bubble up naturally.
// Axios interceptor
axios.interceptors.response.use(
response => response,
error => {
if (error.response) {
// Server responded with error status
const status = error.response.status;
if (status >= 500) {
// Server error — backend already reported to Sentry
// Just show user-friendly message
return Promise.reject(new Error('Something went wrong. Please try again.'));
}
if (status === 401) {
// Expected — handle auth flow
window.location.href = '/login';
return Promise.reject(error);
}
if (status === 422) {
// Validation — handle in form UI
return Promise.reject(error);
}
}
// Network error, timeout, etc. — let it bubble up
// Your Sentry config decides whether to report
return Promise.reject(error);
}
);
The key insight: your interceptor handles UX, not reporting. Don't catch errors just to re-report them.
Enable Inbound Filters
Sentry has built-in server-side filters. Go to Project Settings → Inbound Filters and enable:
- Browser Extensions — known problematic extensions
- Legacy Browsers — old browser versions
- Web Crawlers — bots and spiders
No code required.
Watch Your Error Messages
Sentry groups errors partly by message. Dynamic data in messages breaks grouping:
// Bad — creates thousands of "unique" issues
throw new Error(`Order ${orderId} failed`);
// Good — groups properly, context attached separately
Sentry.withScope(scope => {
scope.setContext('order', { orderId, customerId, amount });
scope.setTag('orderType', 'subscription'); // searchable
Sentry.captureException(new Error('Order processing failed'));
});
Use setContext() for arbitrary data (visible on issue page) and setTag() for searchable key-value pairs. Both preserve grouping while giving you the details you need.
The Result
After proper filtering, your Sentry should have:
- A manageable number of issues (dozens, not thousands)
- Alerts that make you stop and investigate
- Issues you can actually resolve
If you're still drowning in issues, something is genuinely broken—which is exactly what Sentry should be telling you.