Используя Express, как реализовать часто используемую функцию-оболочку для устранения ошибок - PullRequest
0 голосов
/ 01 февраля 2020

Среда: node.js, Express

Я пытаюсь использовать шаблон обработки ошибок, основанный на работе, проделанной Валерием Карповым (создатель Mon goose). Он объясняет шаблон, который он использует в этой статье: Руководство 80/20 по Express Обработка ошибок .

На приведенном ниже упрощенном сервере я могу успешно передавать ошибки в свою обработку ошибок промежуточное программное обеспечение.

const express = require('express');
const app = express();

app.set('view engine', 'ejs');

app.get('/', async function(req, res, next) {

    let catStatus = false;

    function answer(X) {
        return new Promise( function(resolve, reject) {
            if(X) {
                resolve('cat does exist');
            } else {
                reject('whoops, cat does not exist');
            }
        });
    }

    answer(catStatus)
        .then( function(data) {
            res.render('index', { output: data });
        })
        .catch( function(error) {
            next(new Error(error));
        });
});

app.use( function(error, req, res, next) {

    res.render('error', { error });
});

app.listen(8080, function(){
    console.log('listening on port 8080');
});

Однако я застрял на том, как реализовать его шаблон обертки с моей установкой basi c. Содержит ли код внутри моей '/' конечной точки go внутри его '*' конечной точки?

Если да, то что-нибудь go внутри его function wrapAsync(fn)? Должен ли я просто удалить 2 его строки комментариев и оставить все как есть?

app.get('*', wrapAsync(async function(req, res) {
  await new Promise(resolve => setTimeout(() => resolve(), 50));
  // Async error!
  throw new Error('woops');
}));

app.use(function(error, req, res, next) {
  // Gets called because of `wrapAsync()`
  res.json({ message: error.message });
});

app.listen(3000);

function wrapAsync(fn) {
  return function(req, res, next) {
    // Make sure to `.catch()` any errors and pass them along to the `next()`
    // middleware in the chain, in this case the error handler.
    fn(req, res, next).catch(next);
  };
}

1 Ответ

1 голос
/ 01 февраля 2020

I думаю конечная точка * в app.use() - это просто подстановочный знак, указывающий на маршрутизацию всех входящих запросов на этот код, аналогично тому, как работает ваш /.

Но да, вы понимаете правильно. По сути, он говорит, что любое промежуточное ПО, которое выполняет асинхронные запросы, должно использовать эту функцию wrapAsync. Вы можете удалить строки комментариев в реализации wrapAsync, если хотите.

С помощью функции wrapAsync вы можете передать в эту оболочку свои собственные функции промежуточного программного обеспечения asyn c, и она обязательно вызовет ваше промежуточное программное обеспечение asyn c и .catch() обещание вызвать next, чтобы вам не приходилось беспокоиться об этих деталях при написании кода. Вы можете просто выдавать ошибки, и тогда asyn c обертка будет обрабатывать требование Express вызова next() при сбое кода asyn c.

app.use("/", (req, res, next) => {
    verifyRequestorPermissionsAsync(req.params)
        .catch(err => {
            return next(err);
        });
});

С промежуточным ПО wrapAsync вы автоматически вызовет next с отклоненной ошибкой (если она есть), поэтому вы можете немного очистить код (а также избежать случайного забывания вызова next при отклонении).

app.use("/", wrapAsync(async(req, res, next) => {
    await verifyRequestorPermissionsAsync(req.params);
}));

Эти два документа / статьи помогут многое прояснить, если я правильно угадаю, откуда исходит путаница:

...