Always log errors with structured context: user ID, request ID, input data, stack trace. An error message like "Cannot read property of undefined" with no context is impossible to debug — you don't know which user hit it, what they were doing, or how to reproduce it.
Why This Matters
Error logs without context are useless for debugging. "Cannot read property of undefined" without knowing which user, which request, which input, and which code path is impossible to reproduce or fix. Developers waste hours guessing instead of minutes reading structured logs with full context.
An error log that says TypeError: Cannot read properties of undefined (reading 'name') tells you almost nothing. You do not know:
Which user triggered the error
What request they made (URL, parameters, body)
What the application state was at the time
Whether this is a one-off or affecting hundreds of users
How to reproduce it
Without this context, debugging is archaeology: you read the stack trace, guess at what data could cause it, search logs for related events, and try to reconstruct the scenario. This turns a 5-minute fix into a multi-hour investigation.
Structured error logs with context make every error immediately actionable. You see the user, the input, the code path, and the state — and you can often reproduce and fix the issue in minutes.
The rule
Every error log must include: (1) a human-readable message, (2) the original error/stack trace, (3) structured context (user ID, request ID, input data, operation name). Use structured logging (JSON) so logs are searchable and filterable.
Bad example
// Useless error logstry { await processOrder(order);} catch (error) { console.log("Error"); // No details at all console.error(error); // Stack trace but no context console.log("Failed to process order"); // What order? Which user?}