使用Postman请求Express的/role接口时卡住,寻求技术帮助
问题排查:Express.js /role接口请求卡住
此前运行正常的Express后端,现在使用Postman请求http://localhost:5000/role时,Postman一直处于卡住状态。以下是相关代码,请求排查原因:
Role Controller代码
const Role = require("../Models/Role"); const getAllRoles = (req, res, next) => { Role.find({}) .populate("permissions") .then( (roles) => { res .status(200) .json({ success: true, message: "Role retrieved", data: roles }); }, (err) => next(err) ) .catch(() => next(new Error("Can't retrieve all roles"))); }; const createRole = (req, res, next) => { const newRole = new Role({ title: req.body.title, permissions: req.body.permissions, }); Role.create(newRole) .then( (role) => { res .status(201) .json({ success: true, message: "Role created", data: role }); }, (err) => next(err) ) .catch(() => next(new Error("Couldnot Create Role"))); }; const updateRole = (req, res, next) => { Role.findByIdAndUpdate(req.params.id, { $set: req.body }, { new: true }) .then( () => { res.statusCode = 200; res.setHeader("Content-Type", "application/json"); res.json({ success: true, message: "role updated" }); }, (err) => next(err) ) .catch((err) => next(err)); }; const deleteRole = async (req, res, next) => { const role = await Role.findById(req.params.id); if (!role) { res.statusCode = 200; res.setHeader("Content-Type", "application/json"); res.json({ success: true, message: "role is already deleted" }); } Role.findByIdAndDelete(req.params.id) .then( () => { res.statusCode = 200; res.setHeader("Content-Type", "application/json"); res.json({ success: true, message: "role deleted" }); }, (err) => next(err) ) .catch((err) => next(err)); }; module.exports = { createRole, deleteRole, getAllRoles, updateRole, };
Role Router代码
const express = require("express"); const roleRouter = express.Router(); const roleController = require("../Controller/roleController"); roleRouter.get("/", roleController.getAllRoles); roleRouter.post("/", roleController.createRole); roleRouter.patch("/:id", roleController.updateRole); roleRouter.delete("/:id", roleController.deleteRole); module.exports = roleRouter;
app.js代码
const express = require("express"); const createError = require("http-errors"); const path = require("path"); require("dotenv/config"); const app = express(); const cors = require("cors"); const expresssession = require("express-session"); const MongoStore = require("connect-mongo"); // const redisClient = require("./middleware/redisClient") const responseTime = require("response-time") const swaggerUi = require("swagger-ui-express"); const swaggerJSDoc = require("swagger-jsdoc"); const mongoose = require("mongoose"); const passport = require("./middleware/passport"); const UserRouter = require("./Routes/UsersRouter"); const env = require("./configs/dev"); const roleRouter = require("./Routes/RoleRouter"); const permissionRouter = require("./Routes/PermissionRouter"); const url = env.mongoUrl; const connect = mongoose.connect(url); connect.then( () => { console.log("connected Correctly"); }, (err) => { console.error(err); } ); app.use( expresssession({ secret: env.secrectKey, resave: false, saveUninitialized: true, store: new MongoStore({ mongoUrl: env.mongoUrl }), }) ); app.use(cors({ origin: "*" })); app.use(express.static("./assets")); app.use(express.static(path.join(__dirname, "public"))); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(passport.initialize()); app.use(passport.session()); app.use(responseTime); const swaggerOptions = { definition: { openapi: "3.0.0", info: { title: "Green-Me Official", version: "0.1.0", description: "API Routes and Database Schema for GreenMe-Official", }, servers: [ { url: `http://${env.host}/${env.port}`, }, ], }, apis: ["src/routes/UsersRouter.js"], }; const swaggerSpec = swaggerJSDoc(swaggerOptions); app.get("/api-docs.json", (req, res) => { res.setHeader("Content-Type", "application/json"); res.send(swaggerSpec); }); app.use( "/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec, { explorer: true }) ); app.use("/role", roleRouter); app.use((req, res, next) => { next(createError(404)); }); // 原代码此处存在多余注释符号 / module.exports = app;
排查方向与解决方案
1. 数据库查询阻塞
- populate操作慢查询:
getAllRoles中populate("permissions")如果关联的Permission数据量大、无索引,会导致查询超时。- 解决:给Role集合的
permissions字段加索引;在本地执行Role.find({}).populate("permissions")查看耗时;考虑分页返回数据。
- 解决:给Role集合的
- deleteRole异步逻辑漏洞:
await Role.findById(req.params.id)如果数据库连接异常或文档不存在时未捕获异常,会卡住请求;且判断!role返回响应后未终止函数,后续仍会执行删除操作。- 解决:给
await添加try/catch;将deleteRole改为全Promise链式调用,避免混合语法导致的未处理异常。
- 解决:给
2. 中间件异常阻塞
- passport中间件问题:如果passport的session验证或MongoStore存储异常,会卡住请求。
- 解决:暂时注释
passport.initialize()和passport.session(),测试接口是否恢复;检查MongoStore的数据库连接权限。
- 解决:暂时注释
- response-time使用错误:
app.use(responseTime)未调用函数,正确用法是app.use(responseTime()),否则中间件无法正常工作。- 解决:修改为
app.use(responseTime())后重启服务。
- 解决:修改为
3. 未处理错误导致请求挂起
- 全局错误处理缺失:app.js仅定义了404中间件,无错误处理逻辑,当
next(err)调用后,请求会挂起。- 解决:添加全局错误处理中间件:
app.use((err, req, res, next) => { res.status(err.status || 500); res.json({ success: false, message: err.message || 'Internal Server Error' }); });
- 解决:添加全局错误处理中间件:
4. 服务启动问题
- 原app.js中无
app.listen()代码,服务未监听端口会导致请求超时。- 解决:在app.js末尾添加:
app.listen(env.port, () => { console.log(`Server running on http://localhost:${env.port}`); });
- 解决:在app.js末尾添加:
内容的提问来源于stack exchange,提问作者ghulam muhammad
相关产品推荐
相关产品推荐

