我正在客户端上使用 React 和 Typescript 并在服务器上使用 ExpressJS 和 Typescript 构建一个应用程序。 我想确保我在服务器上正确抛出错误并在客户端上正确处理它们。
这是路由方法的删节版本,我必须创建一个 MediaSet(认为是“文件夹”):
const createMediaSet = async (req: Request, res: Response) => {
const values = req.body;
const name: string = values.name + '_'; // '_' only added to force error
const parentId: string | null = values.parent_id;
try {
if (!FileFolderNameRegex.test(name)) {
throw new Error(`Mediaset name '${name}' is invalid!`);
}
const results = await createMediaSetRecord(name, parentId);
const media_set_id = results.rows[0].media_set_id;
res.status(StatusCode.SuccessCreated).json({media_set_id: media_set_id});
} catch (error) {
console.error(error);
res.status(StatusCode.ErrorBadRequest).send({ status: false, message: String(error) });
}
};
然后在客户端,这里是处理上面异步请求的精简代码:
React.useEffect(() => {
if (!isProcessing) {
if (data) {
switch (mode) {
// ... much processing here ...
}
}
if (error) {
console.error(error.message);
alert(`Something went wrong! - ${error.response.data.message}`);
}
}
}, [isProcessing, data, error]);
我的问题有两个:
error.response.data.message
看起来很奇怪,但确实让我收到了从服务器发送的错误消息。看起来很简单。在后端,我要更改的不是针对已知检查抛出通用错误。我会创建一个自定义错误类,如下所示:
class ValidationError extends Error {
constructor(message: string) {
super(message);
this.name = "ValidationError";
}
}
并使用它
try {
if (!FileFolderNameRegex.test(mediaSetName)) {
throw new ValidationError(`Mediaset name '${mediaSetName}' is invalid!`);
} catch (error) {
if (error instanceof ValidationError) {
res.status(StatusCode.BadRequest).send({ status: false, message: error.message });
} else {
console.error(error); // here you could also want to use a custom logging library
res.status(StatusCode.InternalServerError).send({ status: false, message: "An unexpected error occurred." });
}
至于前端,看起来不错,但不能确定,因为我不知道调用是如何进行的。不幸的是,根据响应,您正在使用 axios 或 fetch 或类似的东西,因此 response.error.data.message 是获取响应的方式。您可以做的就是将其移到单独的 utils 文件中,并从那里返回错误作为 errorMessage 或类似的内容,以便在您的组件中使用它。这样,如果您打算处理更多这样的错误,您可以只使用 utils 函数,而不是到处都有 error.response...
export function handleError(error: any): string {
return error?.response?.data?.message || "some default message";
}