JS. Централизованная обработка ошибок

Ребята поделитесь опытом как правильно обрабатывать исключения в JS приложениях. Мои идеи сводятся к тому, чтобы все приложение поместить в блок try/catch и централизовано обрабатывать происходящие исключения. Допустим в какой-либо функции моего приложения посылается исключение такого типа:

throw {
code:304,
name: 'ErrorType'
msg:'Ошибка.....',
file:'*.js',
line:115,
func: function(){}
}

Соответственно в обработчике catch, делается обработка поступившего исключения:

catch(o){
// Можно записать ошибку в БД
log(....);
// Вызвать функцию обработчик (если есть)
o.func();
.....
// Ну и т.д
}


В общем хотелось бы узнать какие-либо паттерны обработки исключений, либо услышать дельный совет.
И скажите пожалуйста, как лучше: иметь всего один блок try/catch или много — на разных уровнях?
Спасибо.
  • Вопрос задан
  • 5702 просмотра
Решения вопроса 1
alienator
@alienator
Никто за вас не решит, что лучше.

Конечно, можно и нужно иметь try/catch на самом верхнем уровне. И дать ему какое-то полезное поведение — записать в лог, вывести красивое окошко и т.п., чтобы не пугать пользователя системными сообщениями.

Это необходимый минимум.

А дальше смотрите глубже. Что вам даст функция-обработчик внутри объекта исключения? Во многих случаях она уже бесполезна; она слишком далеко от точки возникновения ошибки, чтобы попробовать ее исправить (например, вызвать код повторно со значением по умолчанию, подождать освобождения ресурса и т.п., короче, какой-нибудь while/try).

Перед каждым вызовом функции, которая может выбросить исключение, перед каждым входом в компонент у вас есть три пути:

  • обработать какие-то (или все) исключения здесь
  • обработать и передать выше (повторный throw)
  • ничего не делать (передать сразу наверх)


Вам придется опускать обработку исключений глубже хотя бы там, где понадобится finally код. И там, где вы можете сделать что-то осмысленное, прежде чем полностью отваливаться с криками в лог.

И вот там, поглубже, внутри компонента, уже действует ряд разумных рекомендаций:

1. Не ловить всё подряд. Обрабатывать только те исключения, с которыми известно, что делать. Если не совсем известно, делать re-throw.

2. re-throw делать аккуратно. Не надо, опять же, хватать больше от жадности, а потом пропускать исключения ненужных классов. Для ява-скрипта это выражается вот в чем:

Нехорошо:
try {
     // ...
} catch (e) {
     if (! e instanceof MyError) {
          throw e;
     }
    // ...
}


Хорошо:
try {
     // ...
} catch (e if e instanceof MyError) {
    // ...
}


3. То, что вы делаете в finally, важнее, чем то, что делаете в catch. Есть что подчистить — надо подчистить.

4. Не надо терять информацию об ошибке (генерить или ре-генерить исключение более широкого класса). Правда, при разработке либы лучше наоборот, свои мелочи держать в себе и заменять низкоуровневые ошибки на более общие.

Ну, что хотел сказать, то сказал. Удачи.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@gro
JS-приложение основано на обработке событий, как вы его поместите в один try-catch?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы