A payment flow fails for one browser. A form silently drops submissions. An integration has been erroring for a week. Without instrumentation, each is discovered by a customer who bothered to complain — and most do not complain, they leave.
What to capture
- Unhandled server exceptions with stack trace, route, and a request identifier.
- Browser errors including unhandled promise rejections, which are frequently where broken flows hide.
- Failed outbound calls to third parties, with status and response.
- Business events: a case submitted, a payment succeeded, an email sent — with outcomes.
Correlate with a request identifier
Generate an identifier at the edge of every request, attach it to every log line, and surface it in error responses. When a customer reports a problem and quotes it, you can retrieve the whole story instead of searching by timestamp and hoping.
Alert on what indicates harm
Alerting on every exception produces noise that gets muted, and then real failures are missed too. Alert on rate changes: error rate above a threshold, a sudden drop in successful submissions, an integration failing repeatedly. A silent failure — nothing erroring but nothing succeeding either — is the dangerous case, which is why counting successes matters as much as counting errors.
Scrub before sending
Error reports capture request bodies, headers and local variables, which means passwords, tokens and personal data leave your system if you let them. Configure scrubbing deliberately, then test it by triggering an error on a form containing test credentials and checking what actually arrived.
Keep it proportionate
A small site does not need a full observability platform. Server error capture, browser error capture, uptime monitoring and a handful of business counters cover the great majority of real incidents, and can be running in an afternoon.