Нужно ли создавать обработчик ошибок для каждой подпрограммы? - PullRequest
5 голосов
/ 27 мая 2011

Я копирую кусок кода из SO в качестве примера.Подпрограмма содержит обработчик ошибок.Нужно ли создавать обработчик ошибок для всех Sub?*?И когда он встречает метку, такую ​​как ProcError: во время выполнения, он выполняет ее или пропускает?

Ответы [ 2 ]

9 голосов
/ 27 мая 2011

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

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

Более подробно, я отсылаю вас к этим двум превосходным ответам @jtolle:

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

Exit Sub и End Sub довольно интуитивно понятны: первый останавливает выполнение текущего Sub и возвращает управление вызывающей его процедуре (или полностью останавливает выполнение, если процедура не была вызвана другой процедурой). Последний является просто указанием для компилятора, что это где код для этого конкретного Sub заканчивается - и в случае выполнения End Sub ведет себя как Exit Sub.

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

Если в процессе выполнения появляется метка, такая как ProcError:, то ничего особенного не происходит, и выполнение переходит к следующему оператору после метки. Конечно, в вашем примере ProcError: никогда не будет выполнено напрямую (т.е. если не возникнет ошибка), потому что перед ним стоит Exit Sub.


Кстати, блок ProcExit:, вероятно, должен начинаться с On Error Resume Next (т.е. продолжать закрывать все и выходить независимо от каких-либо ошибок) или альтернативно, как указано @Phydaux, On Error Goto 0 (при ошибке , остановить выполнение), в противном случае, если что-то там вызывает ошибку, вы можете попасть в бесконечный цикл пинг-понга между обработчиком ошибок и кодом ProcExit:.

ProcExit:
   On Error Resume Next ' or, alternatively, On Error Goto 0
   Connection.Close
   Connection = Nothing
   Close File
   SomePreciousResource.Release
Exit Sub
2 голосов
/ 27 мая 2011

Exit Sub немедленно выйдет из подпрограммы, как return в Java

End Sub - это просто маркер конца блока подпрограммы, как} в Java

Метка - это просто меткав коде, который используется для определения места назначения прыжка.Если вы не переходили к метке, но приходили туда «регулярно», сама метка будет игнорироваться, но код после метки будет выполняться так, как если бы метки не было, код в вашем примере будет выполняться вплоть доВыход из оператора Sub до тех пор, пока не возникнет ошибка.Если это произойдет, произойдет переход к ProcError

. В этом случае Resume выполнит ProcExit, подробнее здесь

...