Node和Express中未处理的promise错误



我使用NodeJS、ExpressJS和Mongoose制作CRUD API,在执行以下代码时,第29行出现UnhandledPromiseRejectionWarning错误。尽管有一个尝试接球的障碍。

代码:

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
require('../src/db/conn.js');
const MensRanking = require('../src/models/mens.js');
app.use(express.json());
app.get('/', async (req, res) =>{
res.send("<h1>Hello World!</h1>");
})
app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.sendStatus(201).send(insert);
}
catch(e){
res.sendStatus(400).send(e);
}
})  
app.get('/mens', async (req, res) =>{
try{
const getMens = await MensRanking.find({});
res.sendStatus(201).send(getMens);
}
catch(e){
res.sendStatus(400).send(e);
}
})
app.listen(port,()=>{
console.log(`nlistening at http://127.0.0.1:${port}n`);
})

错误:

(node:20016) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:518:11)
at ServerResponse.header (D:projectsrest-api-sectionsrest-tutenode_modulesexpresslibresponse.js:771:10)
at ServerResponse.contentType (D:projectsrest-api-sectionsrest-tutenode_modulesexpresslibresponse.js:599:15)
at ServerResponse.sendStatus (D:projectsrest-api-sectionsrest-tutenode_modulesexpresslibresponse.js:357:8)
at D:projectsrest-api-sectionsrest-tutesrcapp.js:29:13
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:20016) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:20016) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

这是完整的代码库

您应该使用res.status而不是sendStatus

express 中response.status((与response.sendStatus((之间的差异

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
require('../src/db/conn.js');
const MensRanking = require('../src/models/mens.js');
app.use(express.json());
app.get('/', async (req, res) => {
res.send('<h1>Hello World!</h1>');
});
app.post('/mens', async (req, res) => {
try {
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.status(201).send(insert);
}
catch (e) {
res.status(400).send(e);
}
});
app.get('/mens', async (req, res) => {
try {
const getMens = await MensRanking.find({});
res.status(201).send(getMens);
}
catch (e) {
res.status(400).send(e);
}
});
app.listen(port, () => {
console.log(`nlistening at http://127.0.0.1:${port}n`);
});

您正在使用epxress.js的sendStatus函数,因为它会立即将指定的特定代码发送到响应对象,该对象会在设置数据之前触发响应,因此当您的send函数被调用时,响应对象已经发送,因此出现错误:

在将标头发送到客户端后无法设置标头

相反,当您需要设置HTTP响应代码以及数据时,请使用此选项

res.status(RESPONSE_CODE).send(DATA)

在这种情况下,有两个有问题的函数,我只强调其中一个,因为它们有相同的错误:

app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.sendStatus(201).send(insert);
}
catch(e){
res.sendStatus(400).send(e);
}})  
  1. 您已经在尝试块中用res.sendStatus(201(发送了响应,并试图用.send(insert(->引发异常
  2. 之后,您使用res.sendStatus(400(.send(e(再次执行相同的错误

以下代码应该按照您的意图执行:

app.post('/mens', async (req, res) =>{
try{
const addingMensRecords = new MensRanking(req.body);
console.log(req.body);
const insert = await addingMensRecords.save();
res.status(201).send(insert);
}
catch(e){
res.status(400).send(e);
}})  

最新更新