DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. JavaScript Error Handling: Production-Grade Patterns
XLinkedInReddit
MediumFrontend Engineering

JavaScript Error Handling: Production-Grade Patterns

D
DevPrep Team
February 10, 2026·2 min read·0
Table of Contents
  • The Error Hierarchy
  • Custom Error Classes
  • Async Error Handling
  • Global Error Boundaries
  • Production Tips

Good error handling separates amateur code from production code. Here's how we handle errors at Google.

The Error Hierarchy

Error
├── TypeError      // Wrong type operation
├── ReferenceError // Undefined variable
├── SyntaxError    // Parse errors
├── RangeError     // Value out of range
├── URIError       // Bad URI functions
└── Custom errors  // Your domain errors

Custom Error Classes

class AppError extends Error {
  constructor(message, code, statusCode = 500) {
    super(message);
    this.name = "AppError";
    this.code = code;
    this.statusCode = statusCode;
    Error.captureStackTrace?.(this, this.constructor);
  }
}

class NotFoundError extends AppError {
  constructor(resource) {
    super(`${resource} not found`, "NOT_FOUND", 404);
  }
}

class ValidationError extends AppError {
  constructor(field, reason) {
    super(`Validation failed: ${field} ${reason}`, "VALIDATION_ERROR", 400);
    this.field = field;
  }
}

Async Error Handling

// Pattern 1: Go-style error returns
async function fetchUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new AppError("Fetch failed", "FETCH_ERROR", res.status);
    return [await res.json(), null];
  } catch (error) {
    return [null, error];
  }
}

const [user, error] = await fetchUser("123");
if (error) handleError(error);

Global Error Boundaries

// Browser
window.addEventListener("error", (event) => {
  reportToSentry(event.error);
});

window.addEventListener("unhandledrejection", (event) => {
  reportToSentry(event.reason);
  event.preventDefault(); // Prevent console error
});

// React Error Boundary
class ErrorBoundary extends React.Component {
  state = { hasError: false };
  static getDerivedStateFromError() { return { hasError: true }; }
  componentDidCatch(error, info) { reportToSentry(error, info); }
  render() {
    return this.state.hasError
      ? <FallbackUI onRetry={() => this.setState({ hasError: false })} />
      : this.props.children;
  }
}

Production Tips

  • Never swallow errors silently — always log or report
  • Include context: user ID, request ID, timestamp
  • Use error codes, not just messages (messages change, codes don't)
  • Set up source maps for readable stack traces in production

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • The Error Hierarchy
  • Custom Error Classes
  • Async Error Handling
  • Global Error Boundaries
  • Production Tips

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.