Express JS EJS Error-Handling Middleware


Error-handling middleware in Express.js allows you to handle errors that occur during the processing of requests. It is a key part of building robust and reliable applications. Here’s how you can use error-handling middleware in an Express.js application with EJS:

1. Basic Error-Handling Middleware

Error-handling middleware in Express.js has a special signature that includes four arguments: err, req, res, and next. Express recognizes this signature and uses it to handle errors.

Here’s a basic example:

const express = require('express'); const app = express(); // Normal middleware and routes go here // Error-handling middleware app.use((err, req, res, next) => { console.error(err.stack); res.status(500).render('error', { error: err }); });

2. Creating an Error Template

Create an EJS template to display error messages. For example, you might create an error.ejs file in your views directory:

<!DOCTYPE html> <html> <head> <title>Error</title> </head> <body> <h1>Something went wrong!</h1> <p><%= error.message %></p> <pre><%= error.stack %></pre> </body> </html>

3. Generating Errors

You can trigger errors in your routes to see how your error-handling middleware works. Here’s an example route that generates an error:

app.get('/error', (req, res, next) => { // Creating an error and passing it to the next middleware const err = new Error('This is a test error'); err.status = 500; // You can set a custom status code if needed next(err); // Passes the error to the error-handling middleware });

4. Handling Different Types of Errors

You can handle different types of errors differently by checking the err object in your error-handling middleware. For example, you might want to handle 404 errors separately from other types of errors:

app.use((req, res, next) => { // This middleware handles 404 errors for undefined routes res.status(404).render('404', { url: req.originalUrl }); }); // Error-handling middleware for other errors app.use((err, req, res, next) => { console.error(err.stack); res.status(err.status || 500).render('error', { error: err }); });

In this example, you handle 404 errors with a specific template (404.ejs), and other errors are handled with a general error template.

5. Production vs. Development Error Handling

In a production environment, you might not want to expose detailed stack traces to users. Instead, you should log the details and show a user-friendly message:

// Production error handler app.use((err, req, res, next) => { console.error(err.stack); res.status(err.status || 500).render('error', { error: { message: 'Something went wrong!' } }); });

In development, detailed stack traces can be helpful for debugging, so you can include them:

// Development error handler app.use((err, req, res, next) => { res.status(err.status || 500).render('error', { error: err }); });

Summary

  • Basic Error-Handling Middleware: Catch and handle errors with a function that has four parameters (err, req, res, next).
  • Error Template: Create an EJS template to render error messages.
  • Generating Errors: Trigger errors in routes and pass them to the error-handling middleware.
  • Handling Different Errors: Customize responses for different types of errors.
  • Environment-Specific Handling: Adjust error messages based on the environment (development vs. production).