Никто за вас не решит, что лучше.
Конечно, можно и нужно иметь
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. Не надо терять информацию об ошибке (генерить или ре-генерить исключение более широкого класса). Правда, при разработке либы лучше наоборот, свои мелочи держать в себе и заменять низкоуровневые ошибки на более общие.
Ну, что хотел сказать, то сказал. Удачи.