1

我正在使用 Next.js 和next-connect来处理中间件。

但是当我在内部使用多个中间件时,我在尝试处理错误时遇到了问题getServerSideProps

这是我在 getServerSideProps 中的代码,我刚刚使用几个中间件创建了一个处理程序,所以它们都运行,身份验证成功,用户数据应该传递给响应,但如果有任何失败,应该捕获错误并返回重定向到'/login'页面。

import nextConnect from 'next-connect';
import { openDBConnection, retrieveUserInfo } from '@/middlewares/database';
import { verifySessionCookie } from '@/middlewares/firebaseSession';
...
    export const getServerSideProps = async ({ req, res }) => {
        const handler = nextConnect()
            .use(verifySessionCookie)
            .use(openDBConnection)
            .use(retrieveUserInfo);
        try {
            await handler.run(req, res);
            return {
                props: {
                    user: req.user,
                },
            };
        } catch (e) {
            console.log(e);
            return {
                redirect: {
                    destination: '/login',
                    permanent: false,
                }
            };
        }
    }

我没有在任何中间件中定义任何 try/catch 块,因此如果发生错误,可以在任何 api 页面或 getServerSideProps 块中处理。

当只有一个中间件时,每个似乎都可以,在调用verifySessionCookie时返回错误await handler.run(req, res),然后在 catch 块中处理。

但是,当使用代码中显示的 3 个中间件时,如果第一个中间件失败 ( verifySessionCookie),则错误不会在 catch 块中处理。

我尝试next()使用子句在每个中间件中进行调用finally),这样错误就会在 getServerSideProps 中被捕获,但是:

  • verifySessionCookie 执行,失败。
  • openDBConnection 执行,它不会失败。
  • retrieveUserInfo 执行,它失败了。

也许我在这里做错了什么,或者也许 next-connect 不打算以这种方式使用。如果一个中间件没有执行,我不知道如何处理错误。也许我应该在 getServerSideProps 中使用 (req, res) 参数调用独立的异步函数,并停止使用这个 next-connect 插件。

4

1 回答 1

2

next-connect上的文档说onError您可以添加nextConnect

function onError(err, req, res, next) {
  logger.log(err);

  res.status(500).end(err.toString());
  // OR: you may want to continue
  next();
}

const handler = nextConnect({ onError });

或者在您的中间件中,您可以传递一些值req以使其更具可定制性。

在中间件中,您可以添加一个 try/catch 块来传递不同的值req

就像是:

export const middlewareExample = (req, res, next) => {
  try {
    // ...
    req.condition = {
      status: 'succuss, ...',
      message: '...',
      data: {
        // ...
      }
    }
    next();
  } catch(error) {
    res.status(...).end(...);
    // OR: you may want to continue
    req.condition = {
      status: 'error, ...',
      message: '...',
      data: {
        // ...
      }
    }
    next();
  }
}
export const getServerSideProps = async ({ req, res }) => {
  const handler = nextConnect()
  .use(verifySessionCookie)
  .use(openDBConnection)
  .use(retrieveUserInfo);

  await handler.run(req, res);

  if (req.condation.status === 'succuss') {
    return {
      props: {
        user: req.user,
      },
    };
  } else {
    console.log(req.condation.message);
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      }
    };
  }
})

我希望这有帮助。

于 2021-08-30T16:51:48.743 回答