2011-01-25 3 views
60

Допустим, у нас есть структура, как так:Вложенные Try/Catch блокируют плохую идею?

Try 
    ' Outer try code, that can fail with more generic conditions, 
    ' that I know less about and might not be able to handle 

    Try 
    ' Inner try code, that can fail with more specific conditions, 
    ' that I probably know more about, and are likely to handle appropriately 
    Catch innerEx as Exception 
    ' Handle the inner exception 
    End Try 

Catch outerEx as Exception 
    ' Handle outer exception 
End Try 

Я видел некоторые мнения, которые гнездятся Try блоки, как это не рекомендуется, но я не смог найти каких-либо конкретных причин.

Это плохой код? Если да, то почему?

+2

Не уверен, насколько точным является фрагмент. Но нет хексофата, которого вы действительно знаете, когда поймаете Исключение. Это может быть * все *. Рассмотрите возможность использования предложения When, поддерживаемого VB.NET. –

ответ

63

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

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

Тем не менее, исключения должны быть именно такими - исключительными. Программа должна обрабатывать их, но старайтесь избегать их как часть обычного потока выполнения. Они вычислительно дорогие в самых языках (python является заметным исключением).

Еще один метод, который может быть полезным догоняют конкретные типы исключений ...

Try 
    'Some code to read from a file 

Catch ex as IOException 
    'Handle file access issues (possibly silently depending on usage) 
Catch ex as Exception 
    ' Handle all other exceptions. 
    ' If you've got a handler further up, just omit this Catch and let the 
    ' exception propagate 
    Throw 
End Try 

Как отметил Гуча в комментариях ниже, мы также использовать вложенный Try/уловы в нашей обработке ошибок процедур .. .

Try 
     Try 
      'Log to database 
     Catch ex As Exception 
      'Do nothing 
     End Try 

     Try 
      'Log to file 
     Catch ex As Exception 
      'Do nothing 
     End Try 
    Catch ex As Exception 
     'Give up and go home 
    End Try 
+7

Регистрация в фоновом потоке - это место, в котором я буду использовать внутренний try/catch. Я не хочу, чтобы метод заканчивался, потому что он не мог документировать, что он делает. – gooch

+0

@Gooch true, я тоже это сделаю, я добавлю это к своему ответу. – Basic

31

Я на самом деле не думаю, что нет ничего плохого о вложенных Try/Catch блоков, за исключением того, что они могут быть трудно ориентироваться и, скорее всего, знак того, что вы могли бы сделать некоторые рефакторинга (внутренний Try/Catch в свой собственный метод, например).

Но я хочу, чтобы решить этот комментарий:

' Outer try code, that can fail with more generic conditions, 
' that I know less about and might not be able to handle 

Если вы не знаете, как обрабатывать исключения в той или иной ситуации, поверьте мне: не поймать их. Лучше позволить вашему краху приложения (я имею в виду, вы знаете, log, просто не проглотите его), чем поймать то, что вы не знаете, как восстановить, а затем позволить вашему приложению продолжать весело на своем пути в поврежденного состояния. С этого момента поведение будет непредсказуемым.

+0

Это правда. Я бы не захотел, чтобы вы поймали внешнее исключение. Я больше думал о том, что вы можете отключить/перезапустить приложение изящно, а не шокировать пользователя «уродливым сбоем» – Goro

+9

@Goro: В этом случае я бы рекомендовал механизм обработки исключений для всего приложения (например, если это WinForms , обрабатывать событие «Application.UnhandledException»), а не блокировать 'Try' /' Catch' для каждого метода. –

Смежные вопросы