Error Monitoring: The Black Box Recorder
Frontend crashes happen silently. Without monitoring, you are flying blind. How to implement Sentry to catch runtime errors in production.
The Silent Crash
In backend development, managing errors is straightforward.
If your Node.js server crashes, the logs in stderr scream FATAL ERROR. The health check (ping) fails. Kubernetes restarts the pod. The pager (PagerDuty) rings your phone.
You are immediately aware that something is wrong.
In frontend development, failures are silent.
Imagine a user on your e-commerce site. They have spent 30 minutes browsing. They have $500 worth of items in their cart.
They click “Proceed to Checkout”.
The JavaScript engine encounters TypeError: Cannot read properties of undefined (reading 'price').
What happens?
The screen does not explode. The browser does not close.
The UI inevitably freezes. The button spinner spins forever.
The user waits 10 seconds. They click again. Nothing.
They sigh, close the tab, and go to Amazon.
You (the developer) have zero knowledge that this happened.
Your server logs show “200 OK” for the page load.
You assume your software is perfect.
In reality, you are losing thousands of dollars per hour.
This is called Flying Blind. Error Monitoring (Sentry, Datadog, LogRocket) is the solution. It installs a “Black Box Recorder” (SDK) in every user’s browser. When a crash happens, it captures the state, sends it to the cloud, and alerts you.
Why Maison Code Discusses This
At Maison Code, we believe that Observation is the first step of Engineering.
We often inherit codebases from clients who say “Our conversion rate dropped by 20% and we don’t know why.”
We install Sentry, and within 10 minutes, we see thousands of CheckoutError: undefined is not an object coming from Safari users.
The bug was always there. The client was just deaf to it.
We implement monitoring not just to catch bugs, but to Quantify Quality.
We help CTOs move from “I think the site is stable” to “We have a 99.98% crash-free session rate.”
The Tool: Sentry
Sentry is the undisputed industry standard for Application Performance Monitoring (APM) and Error Tracking. It supports every language, but its integration with JavaScript/TypeScript is particularly powerful. It doesn’t just capture the error message; it captures the Context.
Implementation: Integrating Sentry in Next.js
Setting up Sentry used to be hard. Now it is automated.
-
The Wizard: Run
npx @sentry/wizard@latest -i nextjs. This script is magic.- It creates a Sentry Project via API.
- It updates
next.config.jsto upload Source Maps. - It creates
sentry.client.config.ts(Browser),sentry.server.config.ts(Node), andsentry.edge.config.ts(Edge Runtime).
-
Usage (SDK): Sentry automatically hooks into the global
window.onerrorandwindow.onunhandledrejectionevents. You generally don’t need to wrap code intry/catchmanually. -
Manual Capture: Sometimes, you want to catch an error (so the app doesn’t crash) but still report it.
import * as Sentry from "@sentry/nextjs"; async function processPayment() { try { await stripe.confirmPayment(); } catch (error) { // Log to Sentry, but show a nice UI to user Sentry.captureException(error); toast.error("Payment failed, please try again."); } }
Source Maps: The Rosetta Stone
Production JavaScript is Minified and Uglified.
It removes whitespace, renames variables to a, b, c, and shakes off dead code.
This is great for performance, but terrible for debugging.
The Horror:
Error: undefined is not a function
at a (app-123.js:1:432)
at b (app-123.js:1:890)
This tells you nothing.
The Solution: Source Maps (.js.map).
These files map the minified code back to the original TypeScript source.
When Sentry receives a crash report, it looks for the matching Source Map.
It effectively “Un-Minifies” the stack trace.
The Result:
TypeError: user.address is undefined
at calculateShipping (src/utils/shipping.ts:45:12)
at CheckoutForm (src/components/Checkout.tsx:102:4)
Now you know exactly line 45 of shipping.ts is the culprit.
Context is King
Knowing where it crashed is step 1. Knowing who it crashed for is step 2. Sentry allows you to enrich the error event with custom tags and user data.
// In your AuthProvider or Layout
useEffect(() => {
if (user) {
Sentry.setUser({
id: user.id,
email: user.email, // Be careful with PII (GDPR)
segment: user.isVIP ? "VIP" : "Standard"
});
}
}, [user]);
In the Sentry Dashboard, you can now run powerful queries:
- “Show me all crashes affecting VIP users.”
- “Show me all crashes on iOS 17.”
Alert Fatigue: The Boy Who Cried Wolf
The biggest danger with Error Monitoring is Noise.
If your Slack channel #alerts-prod pings every 5 minutes with “Image Failed to Load”, developers will mute the channel.
Then, when the database goes down, nobody notices.
This is Alert Fatigue.
Strategy for Signal-to-Noise:
- Ignore Benign Errors:
Configure
ignoreErrorsinsentry.client.config.ts(e.g.ResizeObserver loop limit). - Spike Protection: Don’t alert on one error. Alert if: “More than 50 users experience this error in 5 minutes.”
Session Replay: The Nuclear Option
Sometimes, a stack trace is not enough. “User says they clicked the button but nothing happened. No error logged.” Session Replay (LogRocket / Sentry Replay) records a video-like reproduction of the user’s session. It records the DOM mutations, mouse movements, and clicks. You can literally watch the user’s screen. “Ah, they triple-clicked the ‘Back’ button while the modal was opening.”
Privacy (GDPR/CCPA):
This is sensitive.
You MUST mask Input fields (Passwords, Credit Cards).
Sentry does this by default (maskAllText: true), turning text into ****.
Verify this configuration manually.
7. Performance Tracing (Sentry Transactions)
Errors are crashes. Transactions are slowness. Sentry traces the entire request lifecycle.
- User clicks “Buy”.
- Browser (
fetch /api/buy) -> 100ms. - Next.js Server (
db.insert orders) -> 500ms. - Stripe API (
charge) -> 2000ms. Total: 2.6s. If you only monitor errors, you think everything is fine. But 2.6s is unacceptable. Sentry shows you the “Waterfall” of the request, highlighting that Stripe is the bottleneck. Fix: Don’t await Stripe. Use a Queue.
8. The User Feedback Widget
When a crash happens, Sentry can automatically pop up a dialog. “It looks like we crashed. Tell us what happened.” User types: “I clicked ‘Apply Coupon’ twice.” This is gold. It connects the “Stack Trace” (Technical) with the “User Intent” (Business). Enable this for verified users to build rapport.
10. Release Health: Deployment Confidence
You deploy Version 2.0. Are errors going up or down? Sentry Release Health tracks “Crash Free Sessions”. v1.0: 99.9% Crash Free. v2.0: 98.0% Crash Free. This triggers an automatic alert: “Regression Detected in v2.0”. You can perform an instant Rollback before customers complain. This is the feedback loop that allows “Deploy on Friday”.
11. Source Map Security
Uploading Source Maps makes debugging easy.
But it also exposes your source code to the public (if you upload them to the CDN).
Competitors can steal your algorithms.
Fix: Upload Source Maps to Sentry Artifacts (Private).
Do not upload .map files to your public CDN.
Configure Sentry to fetch maps internally.
Now you get full stack traces, but the world sees obfuscated code.
12. Conclusion
You can’t fix what you can’t see. Monitoring transforms errors from “Ghost Stories” into “Actionable Tickets”. It allows you to call a customer and say: “We noticed you had an error during checkout. We have fixed it. Here is a 10% coupon.” That is how you turn a failure into loyalty.
Tired of blind debugging?
If your team is spending hours chasing non-reproducible bugs, Maison Code can help. We implement observability stacks that give you X-Ray vision into your production environment.
Flying blind?
We integrate Sentry/Datadog monitoring stacks with Source Maps and Context enrichment. Hire our Architects.