🤬How to add a 500 Error Page in the Express

When building an Express.js application, it's important to be able to diagnose and handle errors. An error 500 typically indicates a server-side error, which could be caused by a variety of issues

In an Express.js application, a 500 error indicates that an internal server error has occurred. To handle 500 errors in your application, you can add an error-handling middleware function that is executed when an error occurs.

  1. Check your server logs: When an error 500 occurs, your server logs may contain more detailed information about the error. Check your server logs for any error messages that may help you identify the root cause of the error.

  2. Use middleware to catch errors: You can use middleware in your Express.js application to catch and handle errors. One popular middleware is express-async-errors, which allows you to handle errors in your async routes. Another middleware is errorhandler, which provides a detailed error page with stack trace information.

  3. Use a service like LogHQ: LogHQ is a service that can help you monitor your application for errors and provide detailed error reports. By integrating logHQ into your Express.js (Node.js in general) application, you can receive alerts when errors occur and get detailed information about the root cause of the error.

Here is an example of how to catch 500 errors in Express.js:

First add a logger util:

// utils/logger.js
const LogshqLogger = require('@logshq.io/node');

// Credentials
const logger = new LogshqLogger({
  project_id: 'SOME-PROJECT-ID',
  api_key: 'SOME-STREAM-KEY',
  environment: process.env.NODE_ENV, // optional
  hostname: 'auth-service', // optional
});

In your App.js add your middleware:

const express = require('express');
const logger = require('./utils/logger')

// middlwares here
// all routes here

app.use(function(err, req, res, next) {
  // Send what you see fit for debugging
  logger.error(err, {
    url: req.originalUrl,
    method: req.method,
    body: req.body,
    params: req.params,
    query: req.query,
    headers: req.headers,
  }); // <= Log here

  res.status(500).send('Internal Server Error!'); // Users will see this
});

In this example, the app.use() method is used to add an error-handling middleware function to the Express.js application. The middleware function takes four arguments: err, req, res, and next. The err argument is the error object that is passed to the middleware function. When this middleware function is called, it logs the error stack trace to the console and sends a message to the client indicating that something broke.

It's important to note that this middleware function should be added after all other route and middleware functions in your application, as it will be executed only if an error occurs in any of the other route or middleware functions.

In this example, the logger.error from the LogsHQ client library is used to create a new log object with the error information. The log object is created with a message, the error itself, the log level, and meta data that includes the URL, HTTP method, request body, params, query, etc...

Once you have set up LogsHQ with your Express.js application, you can set up an alert to be sent to your email address or Slack notification when a 500 error occurs. This can help you quickly identify and diagnose issues with your application once they occur.

How to add a 400 Error Page in the Express

In an Express.js application, a 404 error indicates that a requested resource or route does not exist. To handle 404 errors in your application, you can add a middleware function that is executed when no other middleware function or route handles the request.

Here is an example of how to catch 404 errors in Express.js:

const express = require('express');
const logger = require('./utils/logger')

// middlwares here
// all routes here

// <= handle 404 errors here
app.use(function(req, res, next) {
  logger.error(err, {
    errorType: '404',
    url: req.originalUrl,
    method: req.method,
    body: req.body,
    params: req.params,
    query: req.query,
    headers: req.headers,
  }); // <= Log here
  res.status(404).send("Sorry, that route doesn't exist.");
});

// <= handle 500 errors here
app.use(function(err, req, res, next) {
  // Send what you see fit for debugging
  logger.error(err, {
    errorType: '5XX',
    url: req.originalUrl,
    method: req.method,
    body: req.body,
    params: req.params,
    query: req.query,
    headers: req.headers,
  }); // <= Log here

  res.status(500).send('Internal Server Error!'); // Users will see this
});

In this example, the app.use() method is used to add a middleware function to the Express.js application. The middleware function takes three arguments: req, res, and next. When this middleware function is called, it sets the HTTP status code to 404 and sends a message to the client indicating that the requested route doesn't exist.

It's important to note that this middleware function should be added after all other route and middleware functions in your application, as it will be executed only if no other route or middleware function handles the request. This ensures that it only catches routes that are not handled by any other part of the application.

Unhandled exceptions in an Express.js

To catch unhandled exceptions in an Express.js application, you can use the process object's uncaughtException event. This event is emitted when an unhandled exception is thrown, and you can use it to log the error and gracefully shut down the application.

Here is an example of how to catch unhandled exceptions in an Express.js application:

const logger = require('./utils/logger')
...
process.on('uncaughtException', function (err) {
  logger.error(err, 'Uncaught Exception'); // <= your log here
  process.exit(1);
});

In this example, the process.on() method is used to add a listener for the uncaughtException event. When an unhandled exception is thrown, the listener function is called with the error object. The error stack trace is logged to the console, and the process.exit(1) method is called to exit the Node.js process with a non-zero exit code.

It's important to note that catching unhandled exceptions should be used as a last resort, as it is better to handle errors in a more granular way using try-catch blocks and error-handling middleware functions. However, if an unhandled exception does occur, this technique can help ensure that the application exits gracefully and that the error is logged for debugging purposes.

Also note that starting from Node.js version 17, the uncaughtException event is now considered a deprecated and unsafe way to handle errors. The preferred method is to use the error event on the server instance instead. Here's an example of how to use the error event in Express.js:

...
const server = app.listen(PORT);
...

server.on('error', (error) => {
  logger.error(error, 'Server Error');
  process.exit(1);
});

In this example, the server object is created by calling the listen() method on the app object. The server.on() method is used to add a listener for the error event. When an error occurs, the listener function is called with the error object. The error is logged to the console, and the process.exit(1) method is called to exit the Node.js process with a non-zero exit code.

Last updated