2014-12-15 3 views
13

Я только что начал проверять SailsJS несколько дней назад.
Я понял, что Узел заканчивается всякий раз, когда у меня есть неперехваченное исключение.
У меня есть список контроллеров, и каждый из них вызывает конкретный служебный JS-файл (содержащий логики и вызовы БД) в сервисах /.
Могу ли я написать глобальный обработчик ошибок для всех служб, чтобы любой тип ошибки, возникающий из этих служб, должен обрабатываться им, и соответствующий ответ об ошибке должен быть передан интерфейсу.Рекомендации по обработке исключений в SailsJS

Я попытался использовать process.on ('uncaughtexception') или некоторые основные исключения, но его необходимо добавить к каждому методу службы.

Также я могу иметь одну общую точку для всех сервисных звонков от клиента к серверу, через который все io.socket.post() и io..socket.get() проходит через

Я был бы признателен любой указатель/article, которая показала бы мне общие рекомендации по обработке исключенных исключений в SailsJS и использованию более короткого кода вместо написания избыточного кода во всех сервисах.

+0

Действительно хороший вопрос. Никогда не думал об этом раньше, но политики - это код, который выполняется до вызова действия контроллера. Вы можете попытаться объединить логику контроллера в блок catch try, используя политику, и применить эту политику по умолчанию для всех действий контроллера. Я не пробовал это, и это была просто случайная мысль, которая приходила мне в голову. Дайте мне знать, если это сработает. Я бы попробовал позже –

+0

Это еще не ответ * еще *, но следите за [зонами] (http://strongloop.com/strongblog/announcing-zones-for-node-js/) - среди других вещи он решает проблему обработки ошибок в nodejs. –

ответ

4

Лучшая практика заключается в использовании Domains в вашем контроллере. Это будет обрабатывать исключения в асинхронном коде и относительно прямолинейно.

Вы можете использовать что-то вроде trycatch, чтобы упростить некоторые вещи, но исключения на основе доменов будут наиболее эффективными. Это гарантирует, что исключения не сбой приложения. Просто создайте новый домен в своем контроллере, а запустите свои методы управления внутри этого домена.

Sailsjs, основанный на экспресс, вы можете использовать промежуточное программное обеспечение для соединения, и вы можете легко создать новый домен из промежуточного программного обеспечения. Там такая вещь, как express-domain-middleware. Это может быть самым эстетичным вариантом и наиболее удобным.

Update: Как упоминанием Бенджамин Gruenbaum, домены планируется стать устаревшими в v1 узла. Возможно, вам стоит прочитать Joyents Error Handling Best Practices. Его агностик к структуре, которую вы используете.

Кроме того, вы по-прежнему можете использовать Домены, в то время как нет способа глобально обрабатывать ошибки в node.js в противном случае. После устаревания вы всегда можете легко удалить свою зависимость от Доменов. Тем не менее, лучше не полагаться исключительно на домены.

Strongloop также предоставляет библиотеку, вдохновленную доменами Zone. Это также вариант.

+1

Домены, вероятно, будут устарели в ближайшем будущем. https://github.com/iojs/io.js/issues/66 –

+0

Определите «ближайшее будущее», v0.11 даже не имеет установленной даты выпуска, а v0.12 не будет отображаться, по крайней мере, для другого год, и это оптимистично. AFAIK v1 даже не разрабатывается, его просто до сих пор. Он даже упомянул, что домены, скорее всего, будут перемещены в пакет (из ядра), чтобы поддерживать обратную совместимость. Если вы используете промежуточное ПО, как предлагалось, то вы легко сможете заменить обработку исключений. – tsturzl

+0

Ближайшее будущее - один месяц. Узел недавно был раздвоен в io.js, и большинство основных участников мигрировали (из-за цикла выпуска). Я сказал, что устаревшие не удалены. –

0

Я не пробовал это, но я считаю, что вы должны установить обработчик исключений catch-all в bootstrap.js, используя process.on('uncaughtexception').

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

+0

Я не сбрасываю, но это очень плохая практика, так как ваше приложение испускает необработанное исключение. Это ленивая обработка ошибок, и в любое время, когда это предлагается кому-либо, вы должны сопровождать ее тем фактом, что процесс должен быть остановлен и перезагружен, и вы не должны ** пытаться продолжить то, что вы делали (загрузка, запись файла , db-связь и т. д.). Вы должны остановить все и перезапустить процесс узла. –

+0

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

+0

Не совсем, и я не собирался спускаться на вас, но писать код с неперехваченными исключениями - это просто плохая практика и ловить ее в верхней части приложения, как это просто лениво. Большинство серверов не требуют перезапуска сервера в этих ситуациях. Узел делает. Если вы поймаете исключение и не перезагрузите процесс, узел может застрять в «неизвестном состоянии» (это то, как документы это слово, если я правильно помню). –

1

Его ОК, чтобы исключить ошибку экземпляра узла из-за ошибки программирования, иначе она может продолжаться в противоречивом состоянии и беспорядочной бизнес-логике. В производственной среде сервер может быть перезапущен при сбое, это сбросит его состояние и сохранит его, если ошибка не частая. И во всем этом очень важно регистрировать все. Это относится к большинству настроек узла, включая SailsJS.

Следующий подход может быть использован:

  1. Использование Logger: Выделенный регистратор должен быть доступен для серверных компонентов. Должен быть подключен к службе, которая уведомляет разработчика (электронную почту?) О очень серьезных ошибках.
  2. Распространение ошибок на каждый запрос до конца: Осторожно пересылайте ошибки с любого этапа обработки запроса. В настройках ExperssJs/ConnectJs/middleware, next(err) может использоваться для передачи ошибки в цепочку среднего уровня. Ошибка, улавливающая среднее изделие в конце цепочки, получит эту ошибку, запишет ее в verbose и вернет статус 500. Вы можете использовать Domains или Zones или Promises или async или как хотите обработать запрос и поймать ошибки.
  3. Завершение работы process.on('uncaughtexception'): Войдите в систему erorr, выполните необходимую очистку и повторите ту же ошибку, что и при завершении работы.
  4. User PM2/Forever or Upstart/init.d на linux: теперь, когда процесс завершается из-за плохого исключения, эти инструменты перезапускают его и отслеживают, сколько раз сервер времени сбой. Если сервер терпит крах слишком много времени, полезно прекратить его и принять немедленные меры.
+1

Upstart/init.d будет отличным дополнением к вашей четвертой рекомендации. Так как навсегда один не может перезапустить приложение, если сервер неожиданно перезапустится. PM2 предлагает решение этой проблемы, однако PM2 требует, чтобы узел v0.11 работал эффективно и может иметь неожиданное поведение на v0.10 или ниже, поскольку он полагается на «экспериментальные» модули ядра. – tsturzl

+0

@tsturzl Спасибо. Обновлено в ответ. –