2014-08-28 4 views
1
app.get('/', function(req, res) { 
    doSomethingAsync(function(err) { 
     throw new Error('some unexpected/uncaught async exception is thrown'); 
    }) 
}) 

Possibly unhandled Error: some unexpected/uncaught async exception is thrown 
    at ...stacktrace...:95:9 
From previous event: 
    at ...stacktrace...:82:6) 
    at ...stacktrace...:47:6) 
    at ...stacktrace...:94:18) 

Я пробовал кучу доменов middlewares, но все они работают только для экспресс-оплаты. 3. В настоящее время я нахожусь в экспресс-версии 4.5, и мне интересно, изменился ли этот кусок, этот домен больше не работает.Как визуализировать ответ 500 после непонятной ошибки в express 4?

В настоящее время, когда выбрано исключение, ответ в основном зависает до таймаута.

+0

Использование: 'res.send (500);' –

+0

Хорошо. В асинхронном процессе есть нечеткое исчисление. В этот момент у меня уже нет доступа к объекту res – samol

+0

Передайте ошибку обратному сообщению, если есть ошибка, используйте 'res.status (500) .end()' Примечание: 'res.send (status)' был Устаревший – Jordonias

ответ

1

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

app.use(function(err, req, res) { 
    res.status(err.status || 500); 
    // if you using view enggine 
    res.render('error', { 
     message: err.message, 
     error: {} 
    }); 
    // or you can use res.send();   
}); 

вашего приложение будет поймать любое неперехваченное ошибку маршрутизатора и воздаст «ошибка» страницы

, кстати, не забудьте включить "рядом" на маршрутизаторе Initialization


Edited

app.get('/', function(req, res, next) { 
    try { 
     signin(req.query.username, req.query.password, function(d){ 
      if (d.success) { 
       req.session.user = d.data; 
      } 
      res.end(JSON.stringify(d)); 
     }); 
    } catch(e) { 
     next(e); 
    } 
} 

Надеется, что это поможет

+0

Я пробовал это, но он работает только, если ошибка была брошена внутри маршрутизатора. Если ошибка была брошена внутри асинхронного процесса, то она не поймает ее! – samol

+0

Как обернуть процесс асинхронизации с помощью try & catch, а затем, если ошибка сделает это «next (e)» – DeckyFx

2

Как вы нашли, пытаясь try/catch асинхронной функции не работает. Domains должен работать как раз в курьерском 4 (или выразить 3, или прямо http, что угодно). Я никогда не использовал какое-либо прямое промежуточное ПО, которое пытается внедрить обработку домена, поэтому я не могу сказать, насколько хорошо они работают или не работают.

Я бы предложил только реализовать обработку домена самостоятельно; это не так уж плохо. Один из лучших примеров использования доменов прямо в node's documentation on domains (не первый плохой пример они показывают, второй, хорошо один). Я настоятельно рекомендую прочитать эти документы.

Основная идея довольно проста:

  1. Создать домен
  2. Добавить обработчик ошибок
  3. вызова domain.run(function() { ... }) ввод код, который вы хотите внутри домена в этом выполнения обратного вызова.

Очень простой (и очень локализованным) пример:

// This will alwas throw an error after 100ms, but it will still 
// nicely return a 500 status code in the response. 

app.get('/', function(req, res) { 
    var d = domain.create(); 
    d.on('error', function(err) { 
     res.status(500).send(err.message); 
    }); 
    d.run(function() { 
     setTimeout(function() { 
      throw new Error("some unexpected/uncaught async exception"); 
     }, 100); 
    }); 
}); 

Итак, что будет работать, и это может быть достаточно для вашего случая, но это не самое лучшее решение (Если вы читали документы, вы можете заметить, что это довольно чертовски близко к их плохой пример). Проблема заключается в том (из документации снова):

По самой природе, как бросить работает в JavaScript, почти никогда какой-либо способ безопасно «забрать, где вы остановились», без утечки ссылки, или создания какого-либо другого неопределенного хрупкого состояния.

Лучшее решение (насколько я знаю, так или иначе) - делать то, что рекомендуется в документах узла. Основная идея, которую они предлагают, заключается в использовании cluster (или чего-то подобного) для запуска нескольких рабочих процессов, которые запускают ваш веб-сервер из основного процесса. В каждом из этих рабочих процессов настройте домен, который красиво отправит обратно статус 500 при ошибке, а затем выйдет. Затем, в мастер-процессе, обнаружите, когда работник выходит и просто запускает новый.

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

Примером этого в ответ SO является, вероятно, немного много, но действительно есть отличный пример right in the node docs. Если вы еще этого не сделали, взгляните на него. :)

+0

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

Смежные вопросы