Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Coding Standards|Rules, conventions, and best practices I follow and recommend to teams

Errors & Logs

Define consistent patterns for handling, reporting, and logging errors across the application.

Proper error handling improves debuggability, user experience, and system reliability, while secure and structured logging aids in monitoring and incident response.

Don’t swallow errors silently

Always handle or log errors when using try/catch, promise chains, or callbacks. Silent failures make debugging difficult and can mask serious bugs or broken flows.

TypeScript
Copied!
1try {
2  await sendEmail();
3} catch (e) {
4  // do nothing
5}
TypeScript
Copied!
1try {
2  await sendEmail();
3} catch (e) {
4  logger.error("Failed to send email:", e);
5  throw e; // or handle it gracefully
6}

Use consistent error structures

Use a standardized structure for application errors. This makes it easier to handle errors uniformly in middleware, clients, and logs.

TypeScript
Copied!
throw new AppError("User not found", 404, { userId });

Where AppError might extend Error and include fields like statusCode, context, and isOperational.

Separate operational and programmer errors

Operational errors (e.g., invalid input, DB timeout) are expected and should be handled gracefully. Programmer errors (e.g., undefined is not a function) are bugs and should not be caught silently.

Centralize error handling

Use a centralized error handling mechanism (e.g., Express middleware, global fallback in backend apps) to format responses, log errors, and avoid repetition across routes or services.

TypeScript
Copied!
1app.use((err, req, res, next) => {
2  logger.error(err);
3  const status = err.statusCode || 500;
4  res.status(status).json({ error: err.message });
5});

Always set correct HTTP status codes

Respond with appropriate HTTP status codes to reflect the type of error:

TypeScript
Copied!
res.status(200).json({ error: "Invalid credentials" });
TypeScript
Copied!
res.status(401).json({ error: "Invalid credentials" });

Don’t log sensitive information in production

Avoid logging sensitive data like passwords, tokens, or PII. Mask values or redact fields before logging, especially in error traces that get reported to monitoring tools or stored long-term.

TypeScript
Copied!
logger.warn("Login failed for", { email, password });
TypeScript
Copied!
logger.warn("Login failed for user", { email });

Use proper log levels

Log messages with meaningful severity levels to help filter and prioritize issues:

TypeScript
Copied!
1logger.info("User registered", { userId });
2logger.warn("Payment response took too long");
3logger.error("Payment failed", { error });

Include context in error logs

Include relevant metadata (e.g., user ID, request ID, resource name) with each error or warning log. This makes debugging easier and supports tracing across services.

TypeScript
Copied!
1logger.error("Order processing failed", {
2  orderId,
3  userId,
4  error: err.message,
5});

Show user-friendly error messages

Never expose raw error stacks or internal details to the user. Return clear, generic error messages while logging the full technical details for developers.

JSON
Copied!
1{
2  "error": "TypeError: Cannot read property 'email' of undefined"
3}
JSON
Copied!
1{
2  "error": "Something went wrong. Please try again later."
3}

Retry transient failures when safe

For transient errors (e.g. network issues, rate limits), implement retry logic with backoff. But never blindly retry on all errors — some may be non-recoverable or unsafe to repeat.

File
Copied!
1retry(fetchData, {
2  retries: 3,
3  delay: (attempt) => 1000 * 2 ** attempt,
4});

Provide fallbacks where appropriate

Gracefully degrade functionality by using cached data, default responses, or placeholder components when non-critical errors occur. This improves resilience and user experience.

TypeScript
Copied!
1try {
2  const settings = await fetchUserSettings();
3  applySettings(settings);
4} catch {
5  applyDefaultSettings(); // fallback
6}

Integrate alerting for critical errors

Set up alerting for critical application errors (e.g., service crashes, failed logins spike, DB outages). Use tools like Sentry, Datadog, or Grafana to monitor and respond to production issues in real time.

Styleguide: Errors & Logs | Yevhen Klymentiev