Как и во многих вопросах, связанных с программированием, все зависит ...
Я считаю, что действительно нужно сначала попытаться определить ваш API, чтобы исключительные случаи не могли возникнуть в первую очередь.
Использование Design By Contract может помочь в этом. Здесь можно вставить функции, которые выдают ошибку или сбой и указывают на ошибку программирования (а не на ошибку пользователя). (В некоторых случаях эти проверки удаляются в режиме деблокирования.)
Затем сохраните исключения для общих сбоев, которых нельзя избежать, например, сбой соединения с БД, сбой оптимистической транзакции, сбой записи на диск.
Эти исключения обычно не нужно перехватывать, пока они не достигнут «пользователя». И в результате пользователь должен будет повторить попытку.
Если ошибка является ошибкой пользователя, такой как опечатка в имени или чем-то еще, то исправьте это непосредственно в самом коде интерфейса приложения. Поскольку это обычная ошибка, ее необходимо обработать с помощью удобного сообщения об ошибке, которое может быть переведено и т. Д.
Здесь также полезно наложение приложений. Итак, давайте возьмем пример перевода денег с одного счета на другой:
transferInternal( int account_id_1, int account_id_2, double amount )
{
// This is an internal function we require the client to provide us with
// valid arguments only. (No error handling done here.)
REQUIRE( accountExists( account_id_1 ) ); // Design by contract argument checks.
REQUIRE( accountExists( account_id_2 ) );
REQUIRE( balance( account_id_1 ) > amount );
... do the actual transfer work
}
string transfer( int account_id_1, int account_id_2, double amount )
{
DB.start(); // start transaction
string msg;
if ( !checkAccount( account_id_1, msg ) ) return msg; // common checking code used from multiple operations.
if ( !checkAccount( account_id_2, msg ) ) return msg;
if ( !checkBalance( account_id_1, amount ) ) return msg;
transferInternal( account_id_1, account_id_2, amount );
DB.commit(); // This could fail with an exception if someone else changed the balance while this transaction was active. (Very unlikely but possible)
return "cash transfer ok";
}