WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Node.js · Advanced · question 41 of 100

What are the best practices for error handling in Node.js applications?

📕 Buy this interview preparation book: 100 Node.js questions & answers — PDF + EPUB for $5

Error handling is an essential aspect of writing robust and maintainable Node.js applications. Adopting best practices can result in more efficient, reliable, and easier-to-debug code. Here are some of the best practices for error handling in Node.js applications:

1. **Use built-in Error objects**: Always use the built-in Error objects, such as SyntaxError, TypeError, RangeError, and others to throw or propagate errors. This ensures that the error objects will have a consistent format, including message, name, and stack.

   function divide(a, b) {
     if (b === 0) {
       throw new RangeError('Divisor cannot be zero');
     }
     return a / b;
   }

2. **Use try-catch and async-await**: Always use try-catch blocks for synchronous code, and async-await for asynchronous code. This helps in dealing with both expected and unexpected errors effectively.

   // Synchronous Error Handling
   try {
     const result = divide(42, 0);
   } catch (error) {
     console.log('Error:', error.message);
   }
   
   // Asynchronous Error Handling
   async function fetchData() {
     try {
       const response = await fetch('https://api.example.com/data');
       const data = await response.json();
     } catch (error) {
       console.error('Error fetching data:', error);
     }
   }

3. **Use proper error handling middleware**: In Express, use an error-handling middleware function to handle errors. It should be placed at the end of the middleware chain, after all other middleware and routes.

   // Express error handling middleware
   app.use((error, req, res, next) => {
     res.status(error.status || 500);
     res.json({ error: { message: error.message } });
   });

4. **Use Promises and handle rejections**: When using Promises, always handle them by adding a ‘.catch()‘ method or a ‘try-catch‘ block when using async-await to catch errors. Unhandled promise rejections can cause memory leaks and unexpected application behavior.

   // Using .catch()
   someAsyncFunction()
     .then((result) => console.log('Result:', result))
     .catch((error) => console.error('Error:', error));
   
   // Using try-catch with async-await
   async function processAsync() {
     try {
       const result = await someAsyncFunction();
       console.log('Result:', result);
     } catch (error) {
       console.error('Error:', error);
     }
   }

5. **Centralize error handling**: Use a centralized error handling mechanism to avoid code duplication and improve maintainability.

   // Error handling utility function
   function handleError(error) {
     console.error('Error:', error.message);
   }
   
   // Usage
   try {
     const result = divide(42, 0);
   } catch (error) {
     handleError(error);
   }

6. **Use proper logging**: Use appropriate logging libraries and techniques to log errors with their stack trace, which will be useful while debugging.

7. **Gracefully shutdown the application**: In certain circumstances, it may be necessary to shut down the application gracefully when an error occurs. This can be done by closing all resources, such as database connections, and then exiting the process.

8. **Handle uncaught exceptions**: Add an event listener for the ‘uncaughtException‘ event on ‘process‘. This allows you to log the error and gracefully shut down the application if needed.

   process.on('uncaughtException', (error) => {
     // Log the error and stack trace
     console.error('Uncaught exception:', error);
   
     // Graceful shutdown, if needed
     // ...
   
     // Exit the process
     process.exit(1);
   });

9. **Handle unhandled promise rejections**: Add an event listener for the ‘unhandledRejection‘ event on ‘process‘. This allows you to log the error and take appropriate action.

   process.on('unhandledRejection', (reason, promise) => {
     console.error('Unhandled Rejection at:', promise, 'reason:', reason);
   });

By following these best practices, you can create Node.js applications that are more resilient to errors and easier to debug and maintain.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Node.js interview — then scores it.
📞 Practice Node.js — free 15 min
📕 Buy this interview preparation book: 100 Node.js questions & answers — PDF + EPUB for $5

All 100 Node.js questions · All topics