express make try/catch block 放入中间件避免重复
Express make try/catch block into middleware to avoid duplication
我正在编写我的 expressJs 应用程序,我在我的路由控制器中发现了相同的重复代码来捕获异常,我想知道如何避免这种情况。
我已经检查过这个线程,但是我得到这个错误 "Cannot read property 'catch' of undefined"
: Express Try and Catch in Form of middleware
这是我的route.js
const express = require("express");
const createHttpError = require("http-errors");
const Validator = require("../middlewares/Validator");
const TaskNotFoundException = require("../services/TaskNotFoundException");
const TaskService = require("../services/TaskService");
router.get("/tasks", async (req, res, next) => {
try {
const data = await TaskService.getTasks();
res.send({ code: 200, message: "Success", data });
} catch (error) {
next(createHttpError(500));
}
});
router.get("/task/:id", async (req, res, next) => {
const { id } = req.params;
try {
const data = await TaskService.getTask(id);
res.send({ code: 200, message: "Success", data });
} catch (error) {
if (error instanceof TaskNotFoundException) {
next(createHttpError(404));
} else {
next(createHttpError(500));
}
}
});
and the list goes on
正如您在我的所有路线中看到的那样,我有一个带有可能错误的 try catch 块(只有 500 或 500/404)。我想避免这种重复。
这是我的app.js
const express = require("express");
const bodyParser = require("body-parser");
const createHttpError = require("http-errors");
const api = require("./routes/api");
const app = express();
app.use(express.json());
app.use(bodyParser.json());
app.use("/api", api);
// Catch HTTP 404
app.use((req, res, next) => {
next(createHttpError(404));
});
// Error Handler
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
error: {
status: err.status || 500,
message: err.message,
},
});
});
module.exports = app;
就像我说的,它现在工作得很好,我只是想尽量避免 try catch 代码重复,我已经检查了 Whosebug 中的其他问题,但没有帮助。该解决方案已将 returns 500 与此捕获未定义消息(这不是我想要的)相关联,并且在其他也有 404 的路由上它只是不起作用。
非常感谢!
更新:
我听从了 Heikos 的建议,但仍然无法正常工作
api.js
const express = require("express");
const createHttpError = require("http-errors");
const Validator = require("../middlewares/Validator");
const TaskNotFoundException = require("../services/TaskNotFoundException");
const TaskService = require("../services/TaskService");
const router = express.Router();
router.get("/tasks", async (req, res, next) => {
const data = await TaskService.getTasks();
res.send({ code: 200, message: "Success", data });
});
app.js
const express = require("express");
const bodyParser = require("body-parser");
const createHttpError = require("http-errors");
const api = require("./routes/api");
const app = express();
app.use(express.json());
app.use(bodyParser.json());
app.use("/api", api);
function catchAsyncErrors(middleware) {
return async function(req, res, next) {
try {
await middleware(req, res, next);
} catch(err) {
next(err);
}
};
}
// Catch HTTP 404
app.use(catchAsyncErrors((req, res, next) => {
next(createHttpError(404));
}));
// Error Handler
app.use(catchAsyncErrors((err, req, res, next) => {
res.status(err.status || 500);
res.json({
error: {
status: err.status || 500,
message: err.message,
},
});
}));
module.exports = app;
如果异步中间件函数中的代码包含 await
,您还必须将其包装在 try-catch
块中,否则拒绝的承诺将无法处理。例如:
app.use(async function(req, res, next) {
try {
await Promise.reject("error");
} catch(err) {
next(err);
}
});
将错误传播到错误处理程序,但如果没有 try-catch
块,它会导致“UnhandledPromiseRejection”。
如果将中间件包装到 catchAsyncErrors
函数中,您可以节省一些输入:
function catchAsyncErrors(middleware) {
return async function(req, res, next) {
try {
await middleware(req, res, next);
} catch(err) {
next(err);
}
};
}
router.get("/tasks", catchAsyncErrors(async (req, res, next) => {
const data = await TaskService.getTasks();
res.send({ code: 200, message: "Success", data });
}));
我正在编写我的 expressJs 应用程序,我在我的路由控制器中发现了相同的重复代码来捕获异常,我想知道如何避免这种情况。
我已经检查过这个线程,但是我得到这个错误 "Cannot read property 'catch' of undefined"
: Express Try and Catch in Form of middleware
这是我的route.js
const express = require("express");
const createHttpError = require("http-errors");
const Validator = require("../middlewares/Validator");
const TaskNotFoundException = require("../services/TaskNotFoundException");
const TaskService = require("../services/TaskService");
router.get("/tasks", async (req, res, next) => {
try {
const data = await TaskService.getTasks();
res.send({ code: 200, message: "Success", data });
} catch (error) {
next(createHttpError(500));
}
});
router.get("/task/:id", async (req, res, next) => {
const { id } = req.params;
try {
const data = await TaskService.getTask(id);
res.send({ code: 200, message: "Success", data });
} catch (error) {
if (error instanceof TaskNotFoundException) {
next(createHttpError(404));
} else {
next(createHttpError(500));
}
}
});
and the list goes on
正如您在我的所有路线中看到的那样,我有一个带有可能错误的 try catch 块(只有 500 或 500/404)。我想避免这种重复。
这是我的app.js
const express = require("express");
const bodyParser = require("body-parser");
const createHttpError = require("http-errors");
const api = require("./routes/api");
const app = express();
app.use(express.json());
app.use(bodyParser.json());
app.use("/api", api);
// Catch HTTP 404
app.use((req, res, next) => {
next(createHttpError(404));
});
// Error Handler
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
error: {
status: err.status || 500,
message: err.message,
},
});
});
module.exports = app;
就像我说的,它现在工作得很好,我只是想尽量避免 try catch 代码重复,我已经检查了 Whosebug 中的其他问题,但没有帮助。该解决方案已将 returns 500 与此捕获未定义消息(这不是我想要的)相关联,并且在其他也有 404 的路由上它只是不起作用。
非常感谢!
更新: 我听从了 Heikos 的建议,但仍然无法正常工作
api.js
const express = require("express");
const createHttpError = require("http-errors");
const Validator = require("../middlewares/Validator");
const TaskNotFoundException = require("../services/TaskNotFoundException");
const TaskService = require("../services/TaskService");
const router = express.Router();
router.get("/tasks", async (req, res, next) => {
const data = await TaskService.getTasks();
res.send({ code: 200, message: "Success", data });
});
app.js
const express = require("express");
const bodyParser = require("body-parser");
const createHttpError = require("http-errors");
const api = require("./routes/api");
const app = express();
app.use(express.json());
app.use(bodyParser.json());
app.use("/api", api);
function catchAsyncErrors(middleware) {
return async function(req, res, next) {
try {
await middleware(req, res, next);
} catch(err) {
next(err);
}
};
}
// Catch HTTP 404
app.use(catchAsyncErrors((req, res, next) => {
next(createHttpError(404));
}));
// Error Handler
app.use(catchAsyncErrors((err, req, res, next) => {
res.status(err.status || 500);
res.json({
error: {
status: err.status || 500,
message: err.message,
},
});
}));
module.exports = app;
如果异步中间件函数中的代码包含 await
,您还必须将其包装在 try-catch
块中,否则拒绝的承诺将无法处理。例如:
app.use(async function(req, res, next) {
try {
await Promise.reject("error");
} catch(err) {
next(err);
}
});
将错误传播到错误处理程序,但如果没有 try-catch
块,它会导致“UnhandledPromiseRejection”。
如果将中间件包装到 catchAsyncErrors
函数中,您可以节省一些输入:
function catchAsyncErrors(middleware) {
return async function(req, res, next) {
try {
await middleware(req, res, next);
} catch(err) {
next(err);
}
};
}
router.get("/tasks", catchAsyncErrors(async (req, res, next) => {
const data = await TaskService.getTasks();
res.send({ code: 200, message: "Success", data });
}));