Я бы предположил, что во многих случаях исключения могут быть наиболее полезны, если их сократить до трех типов:
- OperationFailedStateOkException
- Операция не может быть завершена, но состояние локальной и глобальной системы в порядке, за исключением той степени, которая подразумевается этим отказом (например, попытка сослаться на несуществующий элемент в Словаре).
- OperationFailedLocalStateCorruptException
- Операция не может быть завершена, и состояние локальной системы повреждено (например, при попытке обратиться к элементу из поврежденного словаря).
- OperationFailedGlobalStateCorruptException
- Операция не может быть завершена, и состояние глобальной системы повреждено (например, поврежден общий кэш).
Обратите внимание, что во многих случаях вызывающая подпрограмма будет интересоваться не так сильно, как причиной сбоя, так и тем, что подразумевает сбой в состоянии системы. Исключения первого типа, как правило, можно безопасно перехватить и возобновить выполнение, если программист знает, почему они могут произойти и что с ними делать. В некоторых случаях их может потребоваться повторно использовать как исключения второго типа (например, если система не смогла выполнить какую-либо операцию, которая была бы необходима для поддержания согласованности в структуре данных). Те, которые второго типа, должны быть перехвачены и переброшены как первый тип только на уровне, на котором будет отменено поврежденное состояние (например, подпрограмма «Загрузить документ» может перехватывать такие исключения и перебрасывать как исключение «состояние в порядке», если есть). поврежденные структуры данных, использованные при неудачной попытке загрузить документ, будут отброшены). Те, которые третьего типа, как правило, должны вызывать закрытие программы.
Конечно, может быть полезно иметь некоторые градации между различными типами (например, указание на глобальную проблему, достаточную для того, чтобы программа была аккуратно закрыта, сохраняя пользовательские данные, вместо того, чтобы указывать, что все настолько плохо, что попытка сохранить пользовательские данные будет продажные вещи хуже). Тем не менее, перехват исключений и перебрасывание того, что указывает на состояние системы, может быть приятнее, чем просто оставлять более высокие уровни кода, чтобы задаться вопросом, что делать с InvalidArgumentException.