如何使用中间件处理Next.js 13中的异常?

b91juud3  于 2023-08-04  发布在  其他
关注(0)|答案(2)|浏览(285)

我试图使用中间件处理Next.js 13中的异常,但我的代码似乎没有按预期工作。以下是我目前掌握的信息:

import { NextRequest, NextFetchEvent, NextResponse } from "next/server"

export function middleware(req: NextRequest, event: NextFetchEvent) {
    try {
        return NextResponse.next()
    } catch (error: Error | any) {
        return NextResponse.json({
            error: {
                message: error.message,
                status: error.status,
            }
        })
    }
}

字符串
当异常发生时,我希望中间件能够捕获它并返回一个包含错误详细信息的JSON响应。然而,上面的代码似乎没有做到这一点。相反,它只是返回一个500状态错误,因为应用程序中其他地方抛出的异常会导致它崩溃。
我做错了什么?在Next.js 13中,是否有更好的方法使用中间件来处理异常?如果你能帮忙的话,我将不胜感激。

d6kp6zgx

d6kp6zgx1#

当前的Next.js中间件功能可以处理传入的网络请求。它可以处理应用于应用程序中所有路由的转换,但不能处理发生在request/response生命周期之外的错误。
中间件函数中的try-catch块实际上只是围绕着NextResponse.next()语句。如果应用程序中的其他地方发生异常,它不会被此块捕获
以下是关于Next.js GitHub讨论的一些讨论:
1-https://github.com/vercel/next.js/discussions/17832
2-https://github.com/vercel/next.js/discussions/32230
根据目前的情况,最好在应用程序的每个部分分别实现错误处理。这可以在React组件(可能使用error boundaries),API路由(使用try-catch块),甚至可以考虑使用第三方错误跟踪服务,如@sentry/nextjs,以实现更集中的错误日志记录。

f45qwnt8

f45qwnt82#

我最近在使用新的Next.js中间件和API路由的全局错误处理时遇到了同样的限制。
最后,我为全局中间件和异常处理创建了下面的自定义apiHandler Package 器:

import { NextRequest, NextResponse } from 'next/server';

import { errorHandler, jwtMiddleware, validateMiddleware } from './';

export { apiHandler };

function apiHandler(handler: any) {
    const wrappedHandler: any = {};
    const httpMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];

    // wrap handler methods to add middleware and global error handler
    httpMethods.forEach(method => {
        if (typeof handler[method] !== 'function')
            return;

        wrappedHandler[method] = async (req: NextRequest, ...args: any) => {
            try {
                // monkey patch req.json() because it can only be called once
                const json = await req.json();
                req.json = () => json;
            } catch {}

            try {
                // global middleware
                await jwtMiddleware(req);
                await validateMiddleware(req, handler[method].schema);

                // route handler
                const responseBody = await handler[method](req, ...args);
                return NextResponse.json(responseBody || {});
            } catch (err: any) {
                // global error handler
                return errorHandler(err);
            }
        };
    });

    return wrappedHandler;
}

字符串
下面是一个使用apiHandler的示例API路由(/api/account/login):

import { cookies } from 'next/headers';
import joi from 'joi';

import { usersRepo } from '_helpers/server';
import { apiHandler } from '_helpers/server/api';

module.exports = apiHandler({
    POST: login
});

async function login(req: Request) {
    const body = await req.json();
    const { user, token } = await usersRepo.authenticate(body);

    // return jwt token in http only cookie
    cookies().set('authorization', token, { httpOnly: true });

    return user;
}

login.schema = joi.object({
    username: joi.string().required(),
    password: joi.string().required()
});


完整的项目可在https://jasonwatmore.com/next-js-13-app-router-mongodb-user-rego-and-login-tutorial-with-example上获得

相关问题