Next.js API Global Errors & Auth Middleware

Navin Kodag
3 min readDec 30, 2023

Alright this one’s going to be quick. no bs. I was working on a Next.js project and needed a way to handle API Route Errors Globally. Similar to Express in Node.js.

This is what I’ve come up with and it works wonders for my setup.

1. We create a handler function that will take multiple handlers and run them one by one.

import { ApiError } from "next/dist/server/api-utils";
import { NextResponse, NextRequest } from "next/server";

export const custom_middleware =
(...handlers: Function[]) =>
async (req: NextRequest, res: NextResponse) => {
try {
for (const handler of handlers) {
await handler(req, res);
}
} catch (error) {
if (error instanceof ApiError) {
return NextResponse.json(
{ message: error.message },
{ status: error.statusCode }
);
} else {
/// Log server errors using winston or your preferred logger
console.log(error);
return NextResponse.json(
{ message: "Server died for some reason" },
{ status: 500 }
);
}
}
};

2. Now we can add it to a route

app/api/ping/route.ts

import { custom_middleware } from "@/app/lib/server/middleware";
import { ApiError } from "next/dist/server/api-utils";
import { NextRequest, NextResponse } from "next/server";

const main_handler = (req: NextRequest, res: NextResponse) => {
const isAuthenticated = false;

if (isAuthenticated) {
return NextResponse.json({ success: true });
}

throw new ApiError(400, "Some error");
};

/// Wrapping handle in custom_middleware
export const GET = custom_middleware(main_handler);

3. We can see the fruits of our labour in the browser itself.

4. We can add our own custom authentication logic here too.

export const auth_middleware = async (req: NextRequest, res: NextResponse) => {
/// Your auth logic
const isAuthenticated = false;
if (!isAuthenticated) {
throw new ApiError(401, "Unauthorized");
}
};

5. Call it in our custom_middleware

export const custom_middleware =
(...handlers: Function[]) =>
async (req: NextRequest, res: NextResponse) => {
try {
///
/// Auth middleware
await auth_middleware(req, res);

for (const handler of handlers) {
await handler(req, res);
}
} catch (error) {
if (error instanceof ApiError) {
return NextResponse.json(
{ message: error.message },
{ status: error.statusCode }
);
} else {
/// Log server errors using winston or your preferred logger
console.log(error);
return NextResponse.json(
{ message: "Server died for some reason" },
{ status: 500 }
);
}
}
};

6. Test the Auth middleware once

7. Profit 💰

literally me profiting

You can look at the code here: Github

Follow me everywhere. OG Blog

--

--