Notes on Error Logging in React
Goal
Need to optimize error logging to help support team diagnose issues faster. Key metric: time-to-root-cause.
Core Error Structure
JavaScript errors are objects with:
name
: Error type (e.g., "TypeError")message
: Human-readable descriptionstack
: Call stack (non-standard but universally available)
Example:
const err = new Error("API failed");
console.log(err.stack);
// Error: API failed
// at fetchData (utils.js:15:3)
Console.log Behavior
- Outputs multiline string combining name, message and stack
- Not ideal for transport (formatting can cause truncation)
- Serialization quirks:
JSON.stringify(err)
→{}
(useless)- Better:
JSON.stringify(err, Object.getOwnPropertyNames(err))
{"name":"Error","message":"API failed","stack":"..."}
Extended Error Patterns
Common library patterns:
- Override
name
(e.g., "HttpError") - Add custom props (e.g.,
statusCode
,url
) - Maintain original
stack
Example from Axios:
try {
await axios.get('/data');
} catch (err) {
console.log(err.isAxiosError); // true
console.log(err.response.status); // e.g. 404
}
Production Stack Traces
Observation:
- Even in minified builds, axios errors show clean stack traces
- Likely using source maps internally
- Our app should configure source maps for same benefit
Context to Capture
For effective debugging:
- User info (sanitized):
- User ID
- Current route
- Action context:
- API request/response snippets
- Redux state slice
- Custom error wrapper example:
class CheckoutError extends Error { constructor(message, cartState) { super(message); this.cartState = cartState; } }
Sentry Integration
withScope
pattern:
Sentry.withScope(scope => {
scope.setUser({id: user.id});
scope.setExtra('checkoutState', checkoutStore.snapshot());
Sentry.captureException(err);
});
Benefits:
- Attaches context to specific errors
- Doesn't pollute global scope
- Breadcrumbs track user journey
Key Insights
- Always serialize errors with all properties
- Wrap generic errors with domain-specific context
- Source maps are crucial for production debugging
- Sentry scopes > global tags for error-specific context