Почему я получаю UnhandledPromiseRejectionWarning для строки кода, содержащей оператор catch в серверной части моего приложения MERN? - PullRequest
0 голосов
/ 05 апреля 2020

Итак, у меня есть приложение MERN, которое будет использоваться преподавателями класса для ведения административной бухгалтерии. В этом классе студенты делятся на команды по 4 человека и проводят семестр в одном проекте, и я пытаюсь создать внутренний маршрут, который при вызове назначит каждой команде проект.

Модель для коллекции Team содержится в этом файле:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const teamSchema = new Schema({
    teamName: { type: String, required: true },
    projectId: { type: String, required: true, default: "Pending"},
    teamMembers: { type: Array, required: true },
    semester: { type: String, required: true }
}, {
    timestamps: true
});

const Team = mongoose.model('Team', teamSchema);

module.exports = Team;

Тело HTTP-запроса, ожидаемого маршрутом, выглядит следующим образом:

{
    "assignments": [
        {"teamId": "abc", "projectId": "def"},
        {"teamId": "ghi", "projectId": "jkl"}
    ]
}

Вот маршрут:

const router = require('express').Router();
var Team = require("../models/team.model");

router.route('/assignments').post( (req, res) => {
    var assignments = req.body.assignments;
    for (let i = 0; i < assignments.length; i++) {

        Team.findById(assignments[i].teamId)
            .then( (team) => {
                team.projectId = assignments[i].projectId;
                team.save()
                    .then(() => res.json(`Team ${i} assignment updated`))
                    .catch(err => res.status(400).json('Error: ' + err)); // This is line 74 in the full file
            })
            .catch(err => res.status(400).json('Error: ' + err));

    }
});

Это работает, но я получаю следующее предупреждение на стороне сервера:

(node:15264) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at ServerResponse.header (C:\Users\pat1\Documents\COMP523\COMP 523 Admin Tools\backend\express\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (C:\Users\pat1\Documents\COMP523\COMP 523 Admin Tools\backend\express\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\pat1\Documents\COMP523\COMP 523 Admin Tools\backend\express\node_modules\express\lib\response.js:267:15)
    at C:\Users\pat1\Documents\COMP523\COMP 523 Admin Tools\backend\express\routes\team.js:74:51
    at processTicksAndRejections (internal/process/task_queues.js:94:5)
(node:15264) 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(). (rejection id: 1)
(node:15264) [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.

Я смущен этим, потому что я делаю безусловно, есть блоки catch, что более запутанно, так это то, что строка 74 команды. js, откуда, похоже, возникает проблема, - это блок catch. Что тут происходит? Почему это работает, если есть проблема? Спасибо!

1 Ответ

0 голосов
/ 05 апреля 2020

@ padaca Resson: Проблема вызвана тем, что вы пытаетесь отправить ответ в al oop. Но узел допускает один ответ на один запрос. и Team.findById (assignments [i] .teamId)

потому что вы передаете "projectId": "def" или может быть какой-либо другой строкой, но findById всегда ожидает _id, так что это вызывает error и эта ошибка перехватывается блоком catch, и он отправляет ответ об ошибке в первый раз, когда выполняется l oop. и когда второй раз l oop исполняется, он хочет сделать то же самое, то есть попытаться отправить ответ об ошибке клиенту построчно (res.status (400). json ('Error:' + err)). но, как я сказал ранее, узел допускает один ответ на один запрос.

решение: вы можете выполнить ту же задачу:

router.route('/assignments').post( (req, res) => {
    try{
       let resultArr = [];
        for (let i = 0; i < assignments.length; i++) {
           const team = await 
           Team.findByIdAndUpdate(assignments[i].teamId,{projectId: assignments[i].projectId} );
            resultArr.push(`Team ${i} assignment updated`)
          }
res.json(resultArr)
}catch(err)res.status(400).json('Error: ' + err));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...