Вот несколько причин, по которым вы можете переосмыслить этот дизайн.
Во-первых, new ArgumentOutOfRangeException(...);
не производит вашу трассировку стека исключений, которая не генерируется, пока вы не throw
ее. Это может запутать усилия по отладке дальше вниз по стеку. Трассировка стека буквально будет лежать.
Во-вторых, Exception тяжелее, чем какое-то перечисление статуса, чтобы указать, какой тип ошибки произошел. Трудно понять, какую выгоду вы получаете от объекта ответа типа исключение. Предположительно, требуется, чтобы вызывающий абонент впоследствии выполнил набор if (response is FileNotFoundException) ....
и решил, что он хочет сделать для каждого.
Это означает, что вы теряете способность различать ожидаемые исключения и неожиданные исключения в данной функции. Возьмите хорошо понятое уникальное нарушение ограничения. Где-то в вашем вызове или что-то, что вы вызываете, оператор вставки отклоняется СУБД из-за другой записи, имеющей это значение. В зависимости от вашего варианта использования, это либо исключительное обстоятельство, указывающее, что что-то где-то пошло не так (например, поврежденный файл данных), либо результат сам по себе (например, система бронирования, которая предоставила место кому-то другому между показом вам) его наличие и вы принимаете). В первом случае вы бы хотели, чтобы ваш вызывающий абонент выдавал это до точки приложения, которая знает, что с этим делать. Во втором вы можете безопасно вернуть это для звонящего, чтобы сделать его бизнес.
В-третьих, это нарушение принципа наименьшего удивления. Исключения, по замыслу, выручают по умолчанию. Если я явно не поймаю исключение, оно выйдет из моего метода, исключая материал в моих блоках "исключение" и "наконец", приятно вызывая dispose для меня в конце любого использования блоков и повторяется в вызывающей стороне моего метода. То, что он никогда не сделает, это выполнить мой код, который мог бы полагаться на результаты этого вызова метода.
Ваш дизайн здесь игнорируется по умолчанию. Если я не проверю результат явно и не выброшу, он продолжит выполнение моего кода. Рассмотрим этот надуманный пример:
Exception error;
error = GetData(out data);
if (error is DbException) return error;
if (error is ArgumentOutOfRangeException) return error;
// if (error is ....... etc
error = ApplyChangesToData(data);
// if (error is ....... etc
error = SaveData(data);
// if (error is ....... etc
Теперь ставки высоки, если я что-то пропустил, потому что мой частично созданный объект данных может затем пройти через метод ApplyChangesToData и затем сохраниться обратно в базу данных в поврежденной форме. Это может быть так просто, как вы не ожидаете, что внутренне GetData попадет в SocketException или OutOfMemoryException. Это не просто делает вашу абстракцию утечкой, это означает, что, если у вас нет утечки абстракции, ваш код не может быть безопасно написан. Мой код должен знать, говорите ли вы с SqlServer, Oracle, Mongo или чем-то еще, чтобы я мог предвидеть все возможные исключения, которые вы можете перенастроить, и включить их в мои строки if. Конечно, я мог бы добавить другое и бросить любой объект исключения, но, вероятно, вы не хотите этого делать, иначе вы бы его не поймали.
С другой стороны, если вы позволили всплыть исключениям, и я был уверен в том, что такое исключение означало в моем контексте и все еще могло бы содержательно продолжаться, у меня все еще есть возможность перехватить это исключение и отреагировать на него. или подавляя его.
Единственное исключение (каламбур непреднамеренное), о котором я могу подумать, находится на краю уровня службы API, где вы можете зарегистрировать исключение, а затем вернуть общее «что-то пошло не так на сервере», а не разболтать вашу грязную информацию. стирка и предоставление конфиденциальной информации о безопасности через общедоступную конечную точку.
Я надеюсь, что убедил вас (или, если не так, по крайней мере, кто-нибудь из будущих читателей этого предложения) не идти по этому наполненному драконами пути.