Ошибка: невозможно установить заголовки после их отправки - правильно обрабатывать ошибку в экспресс-контроллере - PullRequest
0 голосов
/ 02 июня 2019

У меня проблема с кодом ниже. При возникновении ошибки выполняется оператор if и вызывается res.send. Однако затем код продолжается до вызова res.json ниже. Это приводит к ошибке заголовков.

Является ли использование оператора else единственным правильным способом сделать это? Я бы предположил, что вызов res.send оторвется от функции.

exports.new = function (req, res) {
    let team = new Team();
    team.name = req.body.name;
    team.description = req.body.description;
    team.members = [];

    // save the team and check for errors
    team.save(function (err) {
        if (err) {
            res.status(400).send(err);
        }

        res.status(200).json({
            message: 'Team successfully created',
            team: team
        });
    });
};

Я также пытался использовать req, res, next в качестве параметров функции и использовать следующий метод:

if (err) {
    res.status(400);
    next(err);
}

res.status(200).json({
    message: 'Team successfully created',
    team: team
});

Хотя это не приводит к ошибке, он все равно продолжает вызывать окончательный файл res.status.json (в результате получается 200, а не 400)

Ответы [ 5 ]

2 голосов
/ 02 июня 2019

Вы не можете отправить ответ после вызова res.end, что выполняется внутренне экспрессом при вызове res.send function

В вашем случае просто добавьте return при появлении ошибки

if (err) {
    return res.status(400).send(err);
}
0 голосов
/ 02 июня 2019

Пожалуйста, попробуйте с этим:

team.save(function (err) {
    if (err) {
        return res.status(400).send(err); // here i have added a return
    }

    res.status(200).json({
        message: 'Team successfully created',
        team: team
    });
}

Проблема в том, что когда мы отправляем ответ клиенту, соединение tcp будет закрыто, и повторная отправка данных на тот же объект ответа вызовет ошибку, которую вы получаете в текущем коде.

0 голосов
/ 02 июня 2019

Ошибка, которую вы получаете, заключается в том, что строка кода

  res.status(200).json({
    message: 'Team successfully created',
    team: team
});

вызывается независимо от того, получает она ошибку или нет.В случае ошибки заголовок ответа уже отправляется в этом коде экспрессом

if (err) {
    res.status(400).send(err);
}

Так что, когда экспресс пытается выполнить код ниже, он получает ошибку, которую вы выразили.Ответ должен использовать ответ, предоставленный Рами Джаррар

 // save the team and check for errors
team.save(function (err) {
    if (err) {
        res.status(400).send(err);
    }

    res.status(200).json({
        message: 'Team successfully created',
        team: team
    });
});
0 голосов
/ 02 июня 2019

Ваше предположение неверно по поводу res.send() взлома, он сделает это только если вы return. Вызовите return на res.send() в случае ошибки, чтобы она не продолжалась. Если вы получите сообщение об ошибке, он установит статус 400 (в заголовке), затем ошибка в теле, но, поскольку он не возвращает, он пытается установить статус 200 (в заголовке), вызывая ошибку видя.

// save the team and check for errors
team.save(function (err) {
    if (err) {
        // return here so that it will not continue!
        return res.status(400).send(err);
    }

    // return here if there is no error!
    return res.status(200).json({
        message: 'Team successfully created',
        team: team
    });
});

Экспресс связывает промежуточное ПО вместе, используя function(req, res, next), и можно возвращать результаты через res.send() в нескольких промежуточных программах. Следующее промежуточное программное обеспечение в цепочке вызывается, когда вы return next(), поэтому, если вы хотите вернуть дополнительные данные в другое промежуточное программное обеспечение, например, при успешном выполнении, не будет return res.send(), а вместо этого вызовите return next() после res.send().

0 голосов
/ 02 июня 2019

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

Вам нужно написать: return res.status(400).send(err); или просто использовать if else

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...