On Error Resume Next
От: valmond Россия http://blogs.technet.com/valmond/
Дата: 28.04.05 06:40
Оценка:
Кто-то может внятно объяснить зачем в VB существует конструкция

On Error Resume Next


Что за ситуация, когда нам пофигу есть ошибка или нет, и мы идем дальше?


Навеянно тем, что рзбираю сейчас старый код. где вся обработка ошибок заключается в On Error Resume Next.
Лучше бы этой кострукции вообще небыло.
Заметки — SharePoint & InfoPath
http://blogs.technet.com/valmond/
Re: On Error Resume Next
От: Аноним  
Дата: 28.04.05 06:51
Оценка:
И на случай возникновения вопросов:
On Error Resume Next
'Вообще отключена обработка ошибок.
On Error GoTo <метка>
'Твой обработчик ошибок.
On Error GoTo 0
'Обработка ошибок по умолчанию. Используется для отключения предыдущих конструкций.
Re: On Error Resume Next
От: IronHead Россия  
Дата: 28.04.05 07:08
Оценка:
Конструкция нужна за тем, чтобы после строки кода, где возможно ее возникновение вставить код с обработкой ошибки:
If Err <> 0 Then
WScript.Echo "Error #" & Err.Number & " " & Err.Description
' Здесь можно что-то предпринять ...
WScript.Quit
End If
Re: On Error Resume Next
От: Vi2 Удмуртия http://www.adem.ru
Дата: 28.04.05 07:15
Оценка:
Здравствуйте, valmond, Вы писали:

V>Кто-то может внятно объяснить зачем в VB существует конструкция

V>On Error Resume Next

Это эквивалент такого обработчика ошибок:
   On Error GoTo ErrorHandlerUseless
   . . .
   
ErrorHandlerUseless:
   Resume Next

V>Что за ситуация, когда нам пофигу есть ошибка или нет, и мы идем дальше?

VB будет ВСЕГДА реагировать на наличие ошибки, а мы должны реагировать на его реакцию. Если не реагировать, то задача, скорее всего, будет снята.

V>Лучше бы этой кострукции вообще небыло.


Наивный!
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re: On Error Resume Next
От: al Россия  
Дата: 28.04.05 14:37
Оценка:
Здравствуйте, valmond, Вы писали:

Я практически никогда неиспользую On error goto [Label], по причине того, что это не СТРУКТУРНЫЙ оератор. Практически всегда обработку я выполняю в стиле


On error Resume Next
err.Clear

...


if Err<>0 then
   Err.Clear
   ...
end if

On Error Goto 0


Неструктурность On Error заключается в том, что я не знаю, что следует написать вместо On Error Goto 0 для восстановления предыдущего обработчика. Надо смотреть код выше. А если там есть что-то типа


if .... Then
  On error Goto туда
else
  On error goto сюда
end if


то это вообще отпад (а VB такое волне допускает). Попробуйте сдетать такое со структурными try / catch.
Уж лучше пользоваться обработкой оштюок в стиле C, чем On error goto.


Кроме того, некоторые методы VB вызывают Error когда их об этом не просят. Например SetFocus для невидимого аргумена вызывает ощибку. Спасибо! Практически всегда я пишу


on error resume next
Command1.SetFocus
err.Clear
on error goto 0


Re: On Error Resume Next
От: Igor Polyakov Россия  
Дата: 28.04.05 17:15
Оценка:
Здравствуйте, valmond, Вы писали:

V>Кто-то может внятно объяснить зачем в VB существует конструкция


V>
V>On Error Resume Next
V>


V>Что за ситуация, когда нам пофигу есть ошибка или нет, и мы идем дальше?


Ну например, необходимо написать следующую процедуру:
' Постараться выполнить во чтобы то ни стало критические действия
' Является порцедурой из-за того, что вызывающий не в курсе подробностей
' выполняемых действий, поэтому не сможет обработать ошибок
' Сама не обрабатывает ошибок, т.к. не особо в курсе вызываемых функций и методов
Public Sub PerformCriticaloperations()
    On Error Resume Next
    SomeOperation1
    ...
    Someoperation2
    ...
    SomeObject.Operation3
End Sub


Таким образом мы выполним максимальное количество действий, не задумываясь об их устройстве.
Я согласен, что в общем случае это — плохой стиль. Но когда работаем с объектами, в природе которых не очень разбирамся, наверное, — наилучший.
... << RSDN@Home 1.1.3 stable >>
Re[2]: On Error Resume Next
От: Igor Polyakov Россия  
Дата: 28.04.05 17:15
Оценка:
Здравствуйте, al, Вы писали:

al>Я практически никогда неиспользую On error goto [Label], по причине того, что это не СТРУКТУРНЫЙ оератор. Практически всегда обработку я выполняю в стиле


al>Неструктурность On Error заключается в том, что я не знаю, что следует написать вместо On Error Goto 0 для восстановления предыдущего обработчика. Надо смотреть код выше. А если там есть что-то типа


al>

al>if .... Then
al>  On error Goto туда
al>else
al>  On error goto сюда
al>end if

al>


ИМХО оператор, который скорее вреден, чем полезен — это
On Error Goto 0


Если вы пишете такой код, что вам ручками приходится восстанавливать измененные обработчики, то вам явно стоит задуматься о рефакторинге.
У меня есть предположение, что вы также пишете функции и процедуры на много десятков строк, поэтому на каждый десяток строк вам приходится менять и заново восстанавливать обработчик ошибок.
Если же вы все же решите начинать СТРУКТУРИРОВАТЬ свой код не с обработки ошибок, а с четкости изложения мыслей и формализации операций — то есть будете выделять каждый блок операторов, выполняющий определенное законченное действие в отдельную функцию/процедуру/метод, то:
Ваши функции и процедуры начнут занимать максимум пару десятков строк, а следовательно необходимость ручками восстанавливать обработчики ошибок отпадет сама собой: они будут автоматически восстанавливаться при выходе из функций/процедур/методов.
Но главное — вы получите действительно структурированный легко читаемый код.
И никаких
On Error Goto 0

... << RSDN@Home 1.1.3 stable >>
Re[3]: On Error Resume Next
От: al Россия  
Дата: 29.04.05 05:27
Оценка:
Не всегда программу удается свести к нескольким процедурам из 3-10 строчек. Некоторые сложные алгоритмы требуют больших процедур.

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


sub XXX(name as String)
   dim o as Object
   set o=g_Coll.Item(name)
   o.DoSomething
end sub


Что здесь подвергать рефакторингу?

Используя On Error goto я должен написать



sub XXX(name as String)
   on error goto ErrHandler

   dim o as Object
   set o=g_Coll.Item(name)
   o.DoSomething

   exit sub

ErrHandler:

   ' обработка ошибки

   exit sub

end sub



В этом случае мне абсолютно не нравится ситуация, когда в одном месте я должен разбираться с тем, что же конкретно вызвало ошибку, т.к. мне, например может быть нужно выдать некоторое диагностическое сообщение. Из Err.Code далеко не всегда можно понять, что именно произошло и в каком месте. Например, если у o вызывается несколько методов, то из Err.Code уже невозможно понять, гда именно произошла ошибка.

Поэтому я напишу:



sub XXX(name as String)
   on error resume next

   err.Clear

   dim o as Object
   set o=g_Coll.Item(name)
   if o is Nothing then
      ' моя обработка этой ситуации
      exit sub
   end if

   o.DoSomething
   if err<>0 then
      ' моя обработка этой ситуации
      err.clear
      exit sub
   end if

   on error goto 0 ' согласен, что это не нужно, но для меня это нечто типа операторных скобок - признак того, что где - то в начале вызван On error resume next

end sub


Re[4]: On Error Resume Next
От: Igor Polyakov Россия  
Дата: 29.04.05 17:18
Оценка:
Здравствуйте, al, Вы писали:

al>Не всегда программу удается свести к нескольким процедурам из 3-10 строчек. Некоторые сложные алгоритмы требуют больших процедур.

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

al>Но не обязвтельно такие ситуации возникают в очень больших процедурах. Предположим, что в начале процедура рбращается к колекции за каким-то элементом, после этого вызывает некий метод этого элемента. При этом возможно, что этого элемента нет в коллекции (это одна ошибка), этот элемент есть, но имеет значение Noithing и кроме того вызываемый метод может вызвать ошибку.

В таком случае стоит выделить работу с конкретным элементом в отдельную функцию/процедуру/метод, при этом проверять значение элемента на равенство Nothing до вызова метода.

al>

al>sub XXX(name as String)
al>   on error goto ErrHandler

al>   dim o as Object
al>   set o=g_Coll.Item(name)
al>   o.DoSomething

al>   exit sub

al>ErrHandler:

al>   ' обработка ошибки

al>   exit sub

al>end sub

al>


Sub SafeDoSomething(o As Object)
    On Error Goto ObjectHandler
    o.DoSomething
    Exit Sub
ObjectHandler:
    MsgBox "ObjectHandler"
End Sub

Sub XXX(name As String)
    On Err Goto CollectionHandler
    dim o as Object
    set o=g_Coll.Item(name)
    SafeDoSomething o
    Exit Sub
CollectionHandler:
    MsgBox "CollectionHandler"
End Sub


Сие ИМХО более структурировано и четко выражает суть того, что выполняется в программе.

al>В этом случае мне абсолютно не нравится ситуация, когда в одном месте я должен разбираться с тем, что же конкретно вызвало ошибку, т.к. мне, например может быть нужно выдать некоторое диагностическое сообщение. Из Err.Code далеко не всегда можно понять, что именно произошло и в каком месте. Например, если у o вызывается несколько методов, то из Err.Code уже невозможно понять, гда именно произошла ошибка.

С поиском источника ошибки в целом согласен, но все же (в теории, конечно), такую процедуру лучше разбить на несколько.
... << RSDN@Home 1.1.3 stable >>
Re[5]: On Error Resume Next
От: al Россия  
Дата: 03.05.05 14:23
Оценка:
И такие DoSafeSometing писать для каждого метода? А если методов штук 200 и у некоторых по пять/десять параметров? Пиать кучу оберток и таскать кучу параметров через стек?

А в Вашем коде совершенно не отображено то, что я хочу знать об ошибке вызова DoSomthing в том есте, где я ее вызываю. т.е. SafeDoSomthing должна быть функцией, возвращающей, например, False в случае ошибки. А если DoSomthing — само функция, и мне нужен ее результат. Тогда что, заводить еще один ByRef параметр у SafeDoSomthing? Оч. хороший рефактроинг. Но я лучше буду использовать On Erorr Resume Next.


Re: On Error Resume Next
От: nzeemin Россия http://nzeemin.livejournal.com/
Дата: 10.05.05 17:54
Оценка:
Здравствуйте, valmond, Вы писали:

V>Кто-то может внятно объяснить зачем в VB существует конструкция

On Error Resume Next

V>Что за ситуация, когда нам пофигу есть ошибка или нет, и мы идем дальше?
On Error Resume Next
TalkToLady "Девушка, давайте я вас щас прямо тут трахну!"
On Error Goto 0
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.