Node.js Fundamentals

Learn Node.js from scratch including core concepts, modules, and basic server development.

beginner Backend Development 5 hours

Chapter 11: Error Handling

Chapter 11 of 15

Chapter 11: Error Handling

11.1 Try-Catch

Error handling is crucial for robust applications. Use try-catch for synchronous code.

// Synchronous error handling
try {
    const data = JSON.parse(invalidJson);
    console.log(data);
} catch (error) {
    console.error('Parse error:', error.message);
    // Handle error gracefully
}

Error Types:

  • Error: Generic error
  • TypeError: Wrong type used
  • ReferenceError: Undefined variable
  • SyntaxError: Syntax mistakes
  • Custom Errors: User-defined error types
// Custom error
class ValidationError extends Error {
    constructor(message) {
        super(message);
        this.name = 'ValidationError';
    }
}

try {
    if (!email) {
        throw new ValidationError('Email is required');
    }
} catch (error) {
    if (error instanceof ValidationError) {
        console.error('Validation failed:', error.message);
    }
}

11.2 Error Events

Handle errors in asynchronous operations and event emitters.

// Async/await error handling
async function fetchData() {
    try {
        const data = await someAsyncOperation();
        return data;
    } catch (error) {
        console.error('Async error:', error);
        throw error; // Re-throw if needed
    }
}

// Promise error handling
someAsyncOperation()
    .then(data => {
        // Handle success
    })
    .catch(error => {
        // Handle error
        console.error('Error:', error);
    });

Event Emitter Errors:

const EventEmitter = require('events');
const emitter = new EventEmitter();

// Always handle error events
emitter.on('error', (err) => {
    console.error('Emitter error:', err);
});

// If no error listener, process will crash
emitter.emit('error', new Error('Something went wrong'));

11.3 Error Handling Patterns

Common patterns for handling errors effectively.

Error Middleware (Express):

app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(err.status || 500).json({
        error: {
            message: err.message || 'Internal Server Error',
            ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
        }
    });
});

Graceful Degradation:

try {
    const data = await fetchFromAPI();
    return data;
} catch (error) {
    // Fallback to cached data
    console.warn('API failed, using cache');
    return getCachedData();
}

11.4 Error Handling Best Practices

Follow best practices for comprehensive error handling.

  • Always handle errors, don't ignore them
  • Provide meaningful error messages
  • Log errors for debugging
  • Don't expose sensitive information
  • Use appropriate error types
  • Handle errors at appropriate levels
  • Implement retry logic for transient failures