Published: August 23 2021

Next.js API - Global Error Handler Example & Tutorial

Tutorial built with Next.js 11.1.0

Other versions available:

This is a quick post to show how to implement a global exception handler in a Next.js API.

The main pieces involved in the error handling process that we'll cover in the tutorial are:

  • Global Error Handler - a custom error handler that catches all API exceptions and determines which HTTP response code to return based on the exception type.
  • API Handler Wrapper - a wrapper function for Next.js API router handlers that adds the global error handler to the request pipeline, it also adds support for global middleware to the API.
  • Example Error Throwing API Route Handler - an example api route handler that shows how to throw exceptions that will be handled by the global error handler.

The below code snippets are taken from a Next.js tutorial I posted recently, for the full tutorial or to download and test the code locally see Next.js 11 - User Registration and Login Tutorial with Example App.


Next.js Global Error Handler

Path: /helpers/api/error-handler.js

The global error handler is used catch all errors and remove the need for duplicated error handling code throughout the Next.js tutorial api. It's added to the request pipeline in the API handler wrapper function.

By convention errors of type 'string' are treated as custom (app specific) errors, this simplifies the code for throwing custom errors since only a string needs to be thrown (e.g. throw 'Username or password is incorrect'), if a custom error ends with the words 'not found' a 404 response code is returned, otherwise a standard 400 error response is returned.

If the error is an object with the name 'UnauthorizedError' it means JWT token validation has failed so a HTTP 401 unauthorized response code is returned with the message 'Invalid Token'.

All other (unhandled) exceptions are logged to the console and return a 500 server error response code.

export { errorHandler };

function errorHandler(err, res) {
    if (typeof (err) === 'string') {
        // custom application error
        const is404 = err.toLowerCase().endsWith('not found');
        const statusCode = is404 ? 404 : 400;
        return res.status(statusCode).json({ message: err });
    }

    if (err.name === 'UnauthorizedError') {
        // jwt authentication error
        return res.status(401).json({ message: 'Invalid Token' });
    }

    // default to 500 server error
    console.error(err);
    return res.status(500).json({ message: err.message });
}


API Handler Wrapper

The apiHandler() wrapper function is used by all API route handlers in the tutorial project, global error handling is implemented by executing everything within a try/catch block that passes errors to the errorHandler(). It also enables adding global middleware to the request pipeline by executing each middleware function before the API route handler within the try/catch block, at the moment it has just one piece of middleware for validating JWT tokens.

The apiHandler() function accepts a handler object that contains a method for each HTTP method that is supported by the handler (e.g. get, post, put, delete etc). If a request is received for an unsupported HTTP method a 405 Method Not Allowed response is returned.

import { errorHandler, jwtMiddleware } from 'helpers/api';

export { apiHandler };

function apiHandler(handler) {
    return async (req, res) => {
        const method = req.method.toLowerCase();

        // check handler supports HTTP method
        if (!handler[method])
            return res.status(405).end(`Method ${req.method} Not Allowed`);

        try {
            // global middleware
            await jwtMiddleware(req, res);

            // route handler
            await handler[method](req, res);
        } catch (err) {
            // global error handler
            errorHandler(err, res);
        }
    }
}


Example Error Throwing API Route Handler

This is an example Next.js API route handler that accepts HTTP GET requests and shows how to throw different exceptions that will be handled by the global error handler to return 400 and 404 HTTP responses.

import { apiHandler } from 'helpers/api';

export default apiHandler({
    get: getExampleErrors
});

function getExampleErrors(req, res) {
    // an exception that will return a 400 response
    throw 'Username or password is incorrect';

    // an exception that will return a 404 response because it ends with 'Not Found'
    throw 'User Not Found';
}


API Routing in Next.js

In Next.js the /pages/api folder contains all api endpoints which are routed based on file name, for example the file /pages/api/users/index.js will be mapped to the route /api/users. A route handler exports a default function that accepts an HTTP request (req) and response (res) object. For more info see https://nextjs.org/docs/api-routes/introduction.

 


Need Some NextJS Help?

Search fiverr for freelance NextJS developers.


Follow me for updates

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by