Обработка ошибок с помощью Javascipt и Node.js (then / catch) - PullRequest
0 голосов
/ 28 сентября 2019

Предположим, у меня есть этот псевдокод в файле rout.js:

var pkg = require('random-package');

app.post('/aroute', function(req, res) {
    pkg.impl_func(data, function (err, result) {
        myFunction(entity).then(user=>{
            //DO_STUFF_HERE
            res.render('page.ejs');
        }).catch(err => {
            console.log(err);
            res.render('error.ejs');
        });
    });
});

function myFunction(username) {
   //.....
}

Используемый мной pkg найден на веб-сайте npmjs.myFunction() всегда является моей функцией.

В моем коде вы можете видеть, что я реализовал оператор then / catch для случая, когда myFunction() не удается.Поэтому, когда это происходит, error.ejs отображается.

Но что происходит, когда происходит сбой пакета npm?В терминале я получаю сообщение об ошибке, но на стороне сервера нет обработки ошибок.Это означает, что в случае сбоя пользователь не будет уведомлен с помощью error.ejs, это очевидно, поскольку эта функциональность исключена из моего кода.

Но каковы способы отрисовки error.ejs, когда происходит сбой pkg?

Так как я уже использую технику .then()/.catch() ниже, могу ли я сделать это выше?Другими словами, могу ли я вложить .then()/.catch() операторов?Могу ли я заключить внешний код в try/catch (при этом все еще имея try/catch внутри?)

Ответы [ 2 ]

2 голосов
/ 28 сентября 2019

pkg.impl_func(), по-видимому, реализует ваш типичный интерфейс обратного вызова Node.js (то есть он возвращает ошибку в качестве первого аргумента в случае ошибки или null, если ошибки нет).Вы можете просто проверить наличие ошибки и отобразить error.ejs, когда она присутствует:

app.post('/aroute', function(req, res) {
  pkg.impl_func(data, function (err, result) {
    if (err) {
      res.render('error.ejs');
    } else {
      myFunction(entity).then(user=>{
        //DO_STUFF_HERE
        res.render('page.ejs');
      }).catch(err => {
        console.log(err);
        res.render('error.ejs');
      });
    }
  });
});

В качестве альтернативы, вы можете использовать util.promisify() для преобразования pkg.impl_func() в асинхронныйфункция.Затем вы можете использовать promise.catch() или try-catch внутри функции async, чтобы упростить синтаксис:

const util = require('util')
const impl_func_async = util.promisify(pkg.impl_func)

// traditional promises:
app.post('/aroute', (req, res) => {
  impl_func_async(data).then(result =>
    return myFunction(entity)
  }).then(user => {
    // DO_STUFF_HERE
    res.render('page.ejs')
  }).catch(e => {
    // Will catch thrown errors from impl_func_async and myFunction
    console.log(e)
    res.render('error.ejs')
  })
})

// async-await:
app.post('/aroute', async (req, res) => {
  try {
    const result = await impl_func_async(data)
    const user = await myFunction(entity)
    // DO_STUFF_HERE
    res.render('page.ejs')
  } catch (e) {
    // Will catch thrown errors from impl_func_async and myFunction
    console.log(e)
    res.render('error.ejs')
  }
})
0 голосов
/ 28 сентября 2019

Вы можете использовать простое try/catch, чтобы обернуть все это и визуализировать error.js в этом улове.

Что касается вложения try/catch ... да, вы можете.Однако в этом случае обещание catch() немного отличается от базового try/catch

app.post('/aroute', function(req, res) {

      try {
        pkg.impl_func(data, function(err, result) {
          myFunction(entity).then(user => {
            //DO_STUFF_HERE
            res.render('page.ejs');
          }).catch(err => {
            console.log(err);
            res.render('error.ejs');
          });
        });

      } catch (e) {
        res.render('error.ejs');
      }
    });
});
...