Restify & Bluebird — как передать ошибку из блока catch в обработчик ошибок?

Я работаю над сервером node js и использую bluebird для реализации обещаний. Я понимаю, как использовать промисы, но моя проблема заключается в том, что делать с ошибкой, возвращаемой из промиса. Я попробовал простое решение - просто снова выдал ошибку, но bluebird ее поймал, и клиент так и не получил ответа. Ниже приведен демонстрационный код, чтобы проиллюстрировать мой вопрос:

var restify = require('restify');
var Promise = require('bluebird');

var server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});

server.get('/', function (req, res, next) {
    new Promise(function(resolve, reject){
        reject(new Error());
    }).then(function(res){
        res.send('hello');
    }).catch(function(e){
        throw e;
    });
});

server.on('uncaughtException', function (req, res, route, error) {
    console.log('error');
});

server.listen(7070, function () {
  console.log('%s listening at %s', server.name, server.url);
});

Я ищу способ каким-то образом передать ошибку для восстановления, чтобы она вызвала событие uncaughtException, и я мог бы обработать его, как любое другое необработанное исключение. После небольшого поиска я обнаружил, что могу просто сделать что-то вроде next(new InternalServerError()), и restify вызовет событие для этой конкретной ошибки, но мне это кажется немного странным, поэтому я ищу лучший способ.


person Omer Levi Hevroni    schedule 24.08.2015    source источник


Ответы (1)


Вот PoC, который повторно выдаст любые «возможно необработанные отклонения». Впоследствии они вызовут событие Restify uncaughtException:

var Promise = require('bluebird');
var restify = require('restify');
var server  = restify.createServer();

server.listen(3000);

Promise.onPossiblyUnhandledRejection(function(err) {
  throw err;
});

server.get('/', function (req, res, next) {
  Promise.reject(new Error('xxx')); // no `.catch()` needed
});

server.on('uncaughtException', function (req, res, route, err) {
  console.log('uncaught error', err);
  return res.send(500, 'foo');
});
person robertklep    schedule 24.08.2015
comment
Благодарю вас! это похоже на то, что я хотел. - person Omer Levi Hevroni; 24.08.2015
comment
хорошо, это работает только в том случае, если в ошибке нет сообщения - as restify отображает ответ (используя сообщение об ошибке), а затем вызывает обработчик после события. Это делает все это решение немного неуместным для меня... - person Omer Levi Hevroni; 24.08.2015
comment
Я попытался запустить его на своей машине, и похоже, что исключение не перехватывается доменом рестайфай. Я добавляю process.on('uncaughtException',, и он поймал исключение, но это не очень помогает, так как я не могу что-то вернуть клиенту. Я постараюсь посмотреть позже, смогу ли я найти способ использовать домен для восстановления. - person Omer Levi Hevroni; 24.08.2015
comment
@omer fwiw, я использую [email protected], [email protected] и [email protected] - person robertklep; 24.08.2015
comment
Так что это может быть моя версия восстановления, я только сейчас заметил, что использую устаревшее обновление (3.0.3). Я проверю последнее, но если это сработает для вас, это, вероятно, решение. - person Omer Levi Hevroni; 24.08.2015