Вопрос по exception – Какими принципами руководствуется ваша политика обработки исключений? [закрыто]

27

There is a lot of relativity involved in working with exceptions. Помимо низкоуровневых API, где исключения охватывают ошибки, возникающие в аппаратном обеспечении и ОС, существует неясная область, в которой программист решает, что является исключением, а что является нормальным состоянием.

Как вы решаете, когда использовать исключения?Do you have a consistent policy regarding exceptions?

Если вам нужна библиотека .net для применения политики, подумайтеPolly Michael Freidgeim

Ваш Ответ

12   ответов
7

Эта запись в блоге Эрика Липперта (Eric Lippert), старшего инженера-разработчика программного обеспечения в Microsoft, подводит итоги отличного и краткого наборарекомендации по стратегии исключений.

Короче:

  • Fatal: Terrible errors that indicate your process is totally unrecoverable. Clean up whatever resources you can, but don't catch them. If you're writing code that has the ability to detect such a situation, by all means, throw. Example : Out of memory exception.

  • Boneheaded: Relatively simple errors that indicate your process can't operate on whatever data it's being handed, but would continue on normally if whatever situation caused the error is simply ignored. These are better known as bugs. Don't throw or catch them, but instead prevent them from happening, usually by passing errors or other meaningful indicators of failure that can be handled by your methods. Example: Null argument exception.

  • Vexing: Relatively simple errors that code you don't own is throwing at you. You must catch all of these and deal with them, usually in the same way as you would deal with a Boneheaded exception of your own. Please don't throw them right back out again. Example: Format exception from C#'s Int32.Parse() method

  • Exogenous: Relatively straightforward errors that look a lot like Vexing (from other people's code) or even Boneheaded (from your code) situations, but must be thrown because reality dictates that the code that's throwing them really has no idea how to recover, but the caller probably will. Go ahead and throw these, but when your code receives them from elsewhere, catch them and deal with them. Example: File not found exception.

Из четырех, экзогенные - это те, о которых вы должны думать больше всего, чтобы получить право. Исключение, указывающее, что файл не найден, подходит для метода библиотеки IO, поскольку метод почти наверняка не будет знать, что делать, если файл не найден, особенно если учесть, что ситуация может возникнуть в любое время и что невозможно определить, является ли ситуация временной. Однако создание такого исключения не подходит для кода уровня приложения, поскольку это приложение может получать от пользователя информацию о том, как действовать.

Error: User Rate Limit ExceededassertError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
30

Исключения должныnot быть использован в качестве метода передачи информации внутри между методами внутри вашего объекта, локально вы должны использовать коды ошибок и защитное программирование.

Исключения предназначены для передачи управления из точки, где обнаружена ошибка, в место (выше по стеку), где ошибка может быть обработана, предположительно, потому что локальный код не имеет достаточного контекста для исправления проблемы и чего-то выше по стеку будет иметь больше контекста и, следовательно, сможет лучше организовать восстановление.

При рассмотрении исключений (по крайней мере, в C ++) вы должны учитывать гарантии исключений, которые дает ваш API. Минимальный уровень гарантии должен быть Базовой гарантией, хотя вы должны стремиться (при необходимости) предоставить надежную гарантию. В тех случаях, когда вы не используете никаких внешних зависимостей от суставного API, вы можете даже попытаться предоставить гарантию отсутствия бросков.

N.B.Не путайте гарантии исключений со спецификациями исключений.

Exception Guarantees:

No Guarantee:

There is no guarantee about the state of the object after an exception escapes a method In these situations the object should no longer be used.

Basic Guarantee:

In nearly all situations this should be the minimum guarantee a method provides. This guarantees the object's state is well defined and can still be consistently used.

Strong Guarantee: (aka Transactional Guarantee)

This guarantees that the method will completely successfully Or an Exception will be thrown and the objects state will not change.

No Throw Guarantee:

The method guarantees that no exceptions are allowed to propagate out of the method. All destructors should make this guarantee.
| N.B. If an exception escapes a destructor while an exception is already propagating
| the application will terminate

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

С моей политикой обработки исключений можно ознакомиться по адресу:

http://henko.net/imperfection/exception-handling-policy-throwing-exception/.

(Надеюсь, это не противоречит правилам продвижения веб-сайта, но здесь слишком много информации для вставки.)

0

Другим, возможно, придется исправить / уточнить это, но есть стратегия, называемая (я считаю) «разработкой по контракту», в которой вы явно документируете в своем общедоступном интерфейсе, каковы ожидаемые предварительные условия для каждого метода и гарантированные пост-условия. , Затем при реализации метода любая ошибка, которая мешает вам выполнить постусловия в контракте, должна привести к исключению. Невыполнение предварительных условий считается ошибкой программы и должно привести к ее прерыванию.

Я не уверен, что разработка, основанная на контрактах, связана с вопросом отлова исключений, но в целом вы должны отлавливать только те исключения, которые ожидаете и можете разумно восстанавливаться. Например, большая часть кода не может полноценно восстановиться после исключения «Недостаточно памяти», поэтому нет смысла его перехватывать. С другой стороны, если вы пытаетесь открыть файл для записи, вы можете (и должны) обрабатывать случай, когда файл заблокирован исключительно другим процессом, или случай, когда файл был удален (даже если вы проверили его существование, прежде чем пытаться его открыть).

Как отметил другой комментатор, вам также следует избегать использования исключений для обработки ожидаемых условий, которых можно ожидать и которых следует избегать. Например, в .NET Framework, int.TryParse предпочтительнее, чем int.Parse с try / catch, особенно при использовании в цикле или тому подобном.

0

эта статья от bea (сейчас oracle) - хорошее изложение того, как это сделать:http://www.oracle.com/technology/pub/articles/dev2arch/2006/11/effective-exceptions.html, Это предполагает Java, но вы должны быть в состоянии использовать его и для других сред.

0

Как разработчик C ++, моя собственная политика не состоит в том, чтобы создавать исключения из того, что я считаю общедоступным API-интерфейсом для моих классов / модулей (на самом деле это требование для COM). Тем не менее, я широко использую исключения в реализации частного класса. Например, работа с ATL:

HRESULT Foo()
{
    HRESULT hr = S_OK;
    try {
        // Avoid a whole lot of nested ifs and return code
        // checking - internal stuff just throws.
        DoStuff();
        DoMoreStuff(); // etc.
    } catch ( CAtlException& e ) {
        hr = e;
    }
    return hr;
}

void DoSomething()
{
    // If something goes wrong, AtlThrow( E_FAILED or E_WHATEVER ); 
}
Error: User Rate Limit Exceeded
-1

Не исключение, вызванное языковой средой в соответствии со спецификацией. используемого языка, если он действительно имеет понятие исключений? Я думаю о «делить на ноль» в Java или CONSTRAINT_ERROR в Ada против вообще ничего в C.

Как программист может «решить»? использовать исключения после выбора языка программирования, для которого определены исключения в его структуре?

Изменить. Или вместо "использования" Исключения. Имеете ли вы в виду наличие согласованной и последовательной политики в отношении «обработки»? исключения?

Edit2: вы можете проверитьсвободная глава из книги Стивена Дьюхерста «C ++ Gotchas», в частности, Gotcha 64 и Gotcha 65. Несмотря на то, что он сфокусирован на C ++, уроки, используемые в нем, полезны на других языках.

Error: User Rate Limit Exceeded Daniel
2

Я считаю, что наилучший способ использования исключений зависит от того, какой язык вы используете. Например, Java имеет гораздо более надежную реализацию исключений, чем C ++.

Если вы используете C ++, я рекомендую вам хотя бы попытаться прочитать то, что Бьярн Страуструп (изобретатель C ++) говорит о безопасности исключений. Ссылаться наприложение E его книги "Язык программирования C ++".

Он проводит 34 страницы, пытаясь объяснить, как безопасно работать с исключениями. Если вы понимаете его советы, это все, что вам нужно знать.

2

Я думаю, что обычно существует хороший способ определения исключений на основе доступа к ресурсам, целостности данных и достоверности данных.

Access Exceptions

  • Creating or connecting to any kind of connection (remote, local).
    • Occurs in: Databases, Remoting
    • Reasons: Non-existent, Already in Use or Unavailable, Insufficient/Invalid Credentials
  • Opening, Reading or Writing to any kind of resource
    • Occurs in: File I/O, Database
    • Reasons: Locked, Unavailable, Insufficient/Invalid credentials

Integrity of Data

  • There could be many cases where the integrity of the data matters
    • What it references, what it contains...
    • Look for resources on the methods or code that requires a set of criteria for the data to be clean and in a valid format.
    • Example: Trying to parse a string with the value 'bleh' to a number.

Validity of Data

  • Is this the correct data provided? (It's in the right format, but it might not be the correct set of parameters for a given situation)
    • Occurs in: Database Queries, Transactions, Web Services
    • Example: Submitting a row to a database and violating a constraint

Очевидно, есть и другие случаи, но обычно я стараюсь соблюдать их там, где это необходимо.

Error: User Rate Limit Exceeded
6
  1. Never throw exceptions from destructors.

  2. Maintain some basic level of exception guarantees about the state of the object.

  3. Do not use exceptions to communicate errors which can be done using an error code unless it is a truly exception error and you might want the upper layers to know about it.

  4. Do not throw exceptions if you can help it. It slows everything down.

  5. Do not just catch(...) and do nothing. Catch exceptions you know about or specific exceptions. At the very least log what happened.

  6. When in the exception world use RAII because nothing is safe anymore.

  7. Shipping code should not have suppressed exceptions at least with regards to memory.

  8. When throwing exceptions package as much information as is possible along with it so that the upper layers have enough information to debug them.

  9. Know about flags that can cause libraries like STL to throw exceptions instead of exhibiting unknown behaviour (e.g. invalid iterators / vector subscript overflow).

  10. Catch references instead of copies of the exception object?

  11. Take special care about reference counted objects like COM and warp them in reference counted pointers when working with code that could throw exceptions.

  12. If a code throws an exception more than 2% of the time consider making it an error code for performance's sake.

  13. Consider not throwing exceptions from undecorated dll exports / C interfaces because some compilers optimize by assuming C code to not throw exceptions.

  14. If all that you do for handling exceptions is something akin to below, then don't use exception handling at all. You do not need it.

    main 
    {
         try {
        all code....
        }
        catch(...) {} 
    }
    
3

Исключения являются дорогостоящими по времени обработки, поэтому они должны создаваться только тогда, когда что-то происходит, что в действительности не должно происходить в вашем приложении.

Иногда вы можете предсказать, что может произойти, и код для восстановления после них, и в этом случае целесообразно создать и перехватить исключение, зарегистрировать и восстановить, а затем продолжить. В противном случае их следует просто использовать для обработки непредвиденных ситуаций и корректно завершать работу, собирая как можно больше информации, чтобы помочь с отладкой.

Я - разработчик .NET, и для ловли и броска мой подход таков:

  1. Only try/catch in public methods (in general; obviously if you are trapping for a specific error you would check for it there)
  2. Only log in the UI layer right before suppressing the error and redirecting to an error page/form.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Daniel
2

Контекст, в котором дан этот ответ, является языком Java.

Для обычных ошибок, которые могут появиться, мы обрабатываем их напрямую (например, немедленный возврат, если что-то равно null, пусто и т. Д.). Мы используем фактическое исключение только для исключительных ситуаций.

Однако мы не бросаем проверенные исключения, никогда. Мы создаем подкласс RuntimeException для наших собственных конкретных исключений, перехватывая их, где это применимо, напрямую, а также для исключений, которые вызываются другими библиотеками, API JDK и т. Д., Мы делаем попытку / перехватываем внутренне и регистрируем исключение (если что-то случилось, что действительно не должно & ; t и у вас нет способа восстановления, как исключение файла, не найденного для пакетного задания), или мы оборачиваем исключение в RuntimeException, а затем выбрасываем его. Снаружи кода мы полагаемся на обработчик исключений, чтобы в конечном итоге перехватить это RuntimeException, будь то JVM или веб-контейнер.

Причина этого заключается в том, что он избегает создания принудительных блоков try / catch везде, где у вас может быть четыре экземпляра вызова метода, но на самом деле только один может обработать исключение. Похоже, что это правило, а не исключение (без каламбура ... ой), поэтому, если четвертый может его обработать, он все равно может его перехватить и изучить основную причину исключения, чтобы получить фактическое возникшее исключение ( не беспокоясь об оболочке RuntimeException).

Error: User Rate Limit Exceededonjava.com/pub/a/onjava/2003/11/19/exceptions.html

Похожие вопросы