Одна из основных проблем с иерархиями исключений во многих языках состоит в том, что исключения организованы по типу или по классу вызова, а не по степени серьезности. Очень часто, когда выдается исключение, именно потому, что метод определил, прежде чем что-либо делать, его условия не были выполнены. Вызывающая сторона первой процедуры, которая выбрасывает исключение, могла или не могла сделать что-либо существенное в этот момент. Во многих случаях любые действия, которые будет выполнять вызывающая сторона до вызова подпрограммы, будут действовать только на временные переменные, которые будут испаряться, когда возникнет исключение. Поэтому в подавляющем большинстве случаев, когда что-то вроде подпрограммы LoadDocument () выдает исключение, попытка загрузки документа не окажет влияния на состояние чего-либо, что еще существует. Если неудачная попытка загрузить документ не имела побочных эффектов, и приложение готово справиться с тем фактом, что документ не загружен, нет никаких причин, по которым приложение не должно продолжаться. Трудность состоит в том, чтобы знать, был ли какой-либо побочный эффект.
В существующих системах обработки исключений мне бы не хватало одной функции - виртуального свойства IsResolved в Exception. После обработки блока «catch» система проверит, возвращает ли IsResolved false. Если он не равен NULL и возвращает true, будет вызываться исключение UnresolvedExceptionException с предыдущим исключением в качестве его InnerException (UnresolvedExceptionException.IsResolved будет вызывать метод IsResolved своего InnerException).
Большинство реализаций IsResolved будут проверять, был ли список делегатов функций, возвращающих Boolean, пустым; если нет, верните true, если любой из перечисленных делегатов вернет True. Если исключение подразумевает, что неразмещенный объект был поврежден, метод IsResolved мог возвратить флаг Disposed этого объекта. Если объект был уничтожен, его повреждение больше не будет актуальным. Если объект обернут в блок Using, такое поведение приведет к тому, что исключение будет просачиваться до точки, где объект был удален, но не дальше.
Действительно неприятные исключения, такие как OutOfMemoryException, могли бы сделать их метод IsResolved только счастливым явным вызовом чего-то вроде OutOfMemoryException.AcknowledgeOutOfMemoryCondition. Во многих других подпрограммах, которые генерируют исключения, метод IsResolved немедленно возвращает true (например, Dictionary.GetValue выбрасывает, потому что ключ не найден, тогда, что касается словаря, исключение будет разрешено, как только возникнет исключение) .
К сожалению, я не уверен, насколько хорошо такая схема может быть добавлена к существующей платформе, такой как .net. Тем не менее, если кто-то разработает подобную систему в будущем, было бы полезно включить ее.