Как обрабатывать отклонение необработанного обещания в методе асинхронного объекта в Node.js expressjs?

Я использую асинхронную функцию внутри объекта для отправки ответа в express.js

Код контроллера:

module.exports = {

    async signUpEmail(req, res) {

        /**
         * @description Parameters from body
         * @param {string} firstName - First Name
         * @inner
         */  

        const firstName = req.body.firstName;

        res.send({ success: name });
        throw new Error(); // purposely Done
    }
}

Вопрос:

Поскольку метод signUpEmail в моем случае является асинхронным, и он будет отклонен любым моим асинхронным методом, который здесь выбрасывается, он приходит Error (намеренно помещен туда)

поэтому зарегистрируйте это в консоли.

(node:13537) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error
(node:13537) 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.

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

Код маршрутизатора

    const routes = require('express').Router();
const SignUpController = require('../controllers/signUpController')

// /signup
routes.post('/', SignUpController.signUpEmail);

module.exports = routes;

что-то вроде этого SignUpController.signUpEmail().then(…); Но так как я не вызываю функцию в маршрутах, которые я просто прохожу. Как это можно сделать эффективно?

PS: Пожалуйста, не предлагайте слишком сложные решения. Я новичок в JS и учусь.

Я не использовал цепные обработчики маршрутов, потому что хочу создать модульный, монтируемый обработчик маршрутов.

Пример официального документа


person Ankur Anand    schedule 22.04.2017    source источник
comment
Просто передайте функцию, которая делает: routes.pos('/', (...args) => SignUpController.signUpEmail().then(…))   -  person Bergi    schedule 23.04.2017
comment
@Bergi получает это сейчас TypeError: Невозможно прочитать 'тело' свойства undefined. кажется, что спреды не проходят req .. пробовали console.log, получая неопределенное значение   -  person Ankur Anand    schedule 23.04.2017
comment
Думаю, вам понадобится …signUpEmail(...args)… или что-то еще, что ожидает ваша функция   -  person Bergi    schedule 23.04.2017
comment
@Bergi Берги, да, понял .. если бы вы могли немного просветить, почему это работает так, особенно как (... args) =› становится доступным и что это такое? Потому что если я сделаю` route.post('/', console.log(args));` я получу это ReferenceError: args is not defined было бы очень полезно   -  person Ankur Anand    schedule 23.04.2017
comment
Вы должны поместить его в функцию стрелки, чтобы зарегистрировать его. Но можно и без параметров спреда: routes.post('/', (req, res) => SignUpController.signUpEmail(req, res).then(…))   -  person Bergi    schedule 23.04.2017
comment
@Bergi Теперь я думаю, что получил это (распространение), сделал его более ясным .. не знал о распространении js, все еще изучая JS. поэтому в основном Route.post() требует обратного вызова.. и мы делаем то же самое, разрешая или отклоняя обещание, возвращаемое этим SignUpController.signUpEmail(req, res), и делаем результат, возвращаемый обычной функцией.. Поправьте меня, если я не понял.. Спасибо за ваше большая помощь :)   -  person Ankur Anand    schedule 23.04.2017
comment
К вашему сведению, async/await не является частью ES7, это часть ES2017.   -  person Felix Kling    schedule 23.04.2017


Ответы (1)


В вашем маршруте вам нужно будет добавить оболочку для перехвата выброшенных ошибок:

let wrapper = fn => (...args) => fn(...args).catch(args[2]);

// /signup
routes.post('/', wrapper(SignUpController.signUpEmail));

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

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

// last middleware in chain

app.use(function(err, req, res, next) {
    // handle your errors
});

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

Кроме того, асинхронный шаблон ожидания отлично подходит для написания асинхронного кода, который человеку легко читать в синхронном режиме. Просто помните, что как только вы переходите на асинхронный режим, вы должны оставаться асинхронным! Настоятельно рекомендуется использовать библиотеку промисификации, такую ​​как Bluebird, и вызывать .promisifyAll в nodeback библиотеках.

РЕДАКТИРОВАТЬ: Источник - асинхронная обработка ошибок в Express с обещаниями, Генераторы и ES7

person Kyle Richardson    schedule 22.04.2017
comment
Первый был очень полезен и понял это, но для использования промежуточного программного обеспечения у нас нет перехода к нему (ошибка) как-то работать здесь? - person Ankur Anand; 23.04.2017
comment
let wrapper = fn => (...args) => fn(...args).catch(args[2]); перехватывает выброшенную ошибку из функции внутри оболочки и возвращает ее в качестве следующего маршрута, который затем подхватывается вашим промежуточным программным обеспечением для обработки ошибок. - person Kyle Richardson; 23.04.2017
comment
Отвечает ли это на ваш вопрос? - person Kyle Richardson; 23.04.2017