如何使用 next-connect 在 Next.js 中处理 getServerSideProps 中的错误
How to handle errors inside getServerSideProps in Next.js using next-connect
我正在使用 Next.js 和 next-connect 来处理中间件。
但是当我在 getServerSideProps
中使用多个中间件时,我在尝试处理错误时遇到了问题。
这是我在 getServerSideProps 中的代码,我刚刚使用几个中间件创建了一个处理程序,然后所有这些 运行,身份验证成功并且用户数据应该传递给响应,但是如果任何失败,应该捕获错误并 return 重定向到 '/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 块中处理时,错误是 returned。
但是当使用代码段中显示的 3 个中间件时,如果第一个中间件失败 (verifySessionCookie
),则不会在 catch 块中处理错误。
我尝试使用 finally
子句在每个中间件中进行 next()
调用),这样错误就会在 getServerSideProps 中被捕获但是:
- verifySessionCookie 执行,失败。
- openDBConnection 执行,它不会失败。
- retrieveUserInfo 执行,失败。
也许我在这里做错了什么,或者 next-connect 不打算以这种方式使用。如果一个中间件没有执行,我不知道如何处理错误。也许我应该在 getServerSideProps 中使用 (req, res) 参数调用独立的异步函数,并停止使用这个 next-connect 插件。
next-connect 上的文档说您可以在 nextConnect
上添加 onError
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,
}
};
}
})
希望对您有所帮助。
我正在使用 Next.js 和 next-connect 来处理中间件。
但是当我在 getServerSideProps
中使用多个中间件时,我在尝试处理错误时遇到了问题。
这是我在 getServerSideProps 中的代码,我刚刚使用几个中间件创建了一个处理程序,然后所有这些 运行,身份验证成功并且用户数据应该传递给响应,但是如果任何失败,应该捕获错误并 return 重定向到 '/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 块中处理时,错误是 returned。
但是当使用代码段中显示的 3 个中间件时,如果第一个中间件失败 (verifySessionCookie
),则不会在 catch 块中处理错误。
我尝试使用 finally
子句在每个中间件中进行 next()
调用),这样错误就会在 getServerSideProps 中被捕获但是:
- verifySessionCookie 执行,失败。
- openDBConnection 执行,它不会失败。
- retrieveUserInfo 执行,失败。
也许我在这里做错了什么,或者 next-connect 不打算以这种方式使用。如果一个中间件没有执行,我不知道如何处理错误。也许我应该在 getServerSideProps 中使用 (req, res) 参数调用独立的异步函数,并停止使用这个 next-connect 插件。
next-connect 上的文档说您可以在 nextConnect
onError
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,
}
};
}
})
希望对您有所帮助。