Когда имеет смысл ставить "on Error Resume Next"

Тема в разделе "Lotus - Программирование", создана пользователем Omh, 19 мар 2009.

  1. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Доброго дня разработчикам!

    Как известно, у нормального лотусного программиста функция выглядит так:
    Код (Text):
    Function Function_name
    On Error Goto Errh
    'Тело функции
    Exit Function
    Errh:
    Call ErrHandler
    Exit Function
    End Function
    Сам errorhandler может немного отличаться, я про саму конструкцию.

    Но при этом внутри ф-ии иногда используется конструкция вида
    Код (Text):
    On Error Resume Next
    'Потенциально опасная операция
    On Error Goto Errh
    Хотел поинтересоваться, кто и когда использует вторую конструкцию и вообще стоит ли её использовать.

    Что бы не быть голословным приведу примеры, что зачастую ставлю внутрь "On Error Resume Next":
    1. Set doc = db.GetDocumentByID/UNID(ID) (ну это у меня вынесено в отдельную ф-ию)
    2. Call Dc.AddDocument(doc)
    3. MkDir
    4. Kill
    5. RmDir
    6. Dir

    Иногда использую такую конструкцию (может кому пригодиться):
    Код (Text):
    On Error Resume Next
    Error 1001
    'Потенциально опасная операция
    On Error Goto Errh
    If Err <> 1001 Then 'Потенцально опасная операция таки вывалилась :)
    Вообщем, вопрос таков: кто для чего испрользует эти конструкции, стоит ли вообще их использовать и где кончается нормальная практика и начинается злоупотребление? :)
    Спасибо!
     
  2. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    не ну взял и все наиболее употр*цензура*емые варианты перечислил...
    например, NotesDatabase.Open()...
    в общем, в любом случае, когда нужно получить результат некоторой операции и пойти дальше, а не париться с обработкой...
     
  3. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Кстати db.Open я раньше тоже иногда ставил в такой обработчик.
    Сейчас юзаю конструкцию, которая пока что работает железно:
    Код (Text):
    dim db as New notesDatabase("", "")
    Call db.Open(Some_Server, Some_Path)
    if db.IsOpen then
    'Всё в поряде
    else
    'Скорее всего ошибка в Some_Server/Some_Path
    End if
    Я к чему спросил-то?
    Тут услышал из уст коллеги, что On Error Resume Next не надо использовать никогда.
    Вот и решил узнать, один ли я столь убог, что юзаю On Error Resume Next
     
  4. Medevic

    Medevic Что это ? :)
    Lotus team

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Я редко использую, т.к. в случае ошибки часто нельзя выполнять следующую строку.
    Например:
    Код (Text):
    Set doc = db.GetDocumentByID/UNID(ID)
    Call doc.ReplaceItemValue("", "")
    Обычно я использую следующую конструкцию:
    Код (Text):
    Function Function_name
    On Error Goto Errh
    'Тело функции
    Process:
    'Тело функции
    Exit Function
    Errh:
    'обрабатываем ошибку, если надо
    Resume Process
    End Function
     
  5. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    дай ему под коленку, скажи, что убогие программеры кодебая передают привет! :)
    а чем он это аргументировал? или он какой-то явист или ему подобный, лихо использующий try {} catch {}? :)
     
  6. oshmianski

    oshmianski Гость

    мои 5 копеек.
    вообще у нас принято в обязательном порядке использовать обработчик ошибок вида

    function f_name (params) as boolean
    On Error Goto ErrorHandler
    f_name = false
    'код
    f_name = true
    Ex:
    Exit Function
    ErrorHandler:
    'обработка ошибки
    Resume Ex
    End Function

    что касается Resume Next, то часто использую в связке с db.GetDocumentByUNID

    on error 4091 resume next
    Set doc = db.GetDocumentByUNID (unid)

    if (doc is Nothing) then

    ну и так далее.

    использовать же

    On Error Goto ErrorHandler
    On Error Resume Next
    'код для проверки
    On Error Goto ErrorHandler

    на мой взгляд не совсем красиво, ибо может запутывать логику.
    я бы постарался 'код для проверки выделить в функцию.
    но в конструкции не вижу ничего криминального.
     
  7. olegber

    olegber Гость

    Как мне кажется все ошибки должны обрабатываться в одном месте:

    sub Test
    on error goto ErrEx:

    exit sub

    ErrEx:
    Select Case Err
    Case 1001:print "User Error 1001"
    Case 1002:print "User Error 1002"
    Case 1003:print "User Error 1003"
    Case 1004:print "User Error 1004"
    Case 4091: resume Next
    Case Else
    print cstr(Er)
    End Select
    exit sub
    end sub
     
  8. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    в очень многих случаях, ошибку просто не нужно обрабатывать как-нибудь особенно, просто нужно, чтобы программа не выпала в осадок из-за ее возникновения, в этих случаях и используется "местная" конструкция, т.к. в ином случае приходится "бегать смотреть" что же там делается...
     
  9. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.082
    Симпатии:
    300
    как и везде кетч эксепшн и продолжение выполнения, происходит в местах, где использование кода (часто не тобой написанного) может вызвать исключение, но оно ситуативно некритично и решение нужно вынести в др. месте программы (а здесь - отметить ситуацию)

    как пример - файловые операции типа удаления и создание каталога, файлов
    файл удален уже или не был создан, каталог уже существует (а доп. проверка - тот же код)

    или вариант когда не хотелось бы в обработке исключения добавлять код, кот. тоже может вызвать исключение
     
  10. abbatik

    abbatik Lotus team
    Lotus team

    Регистрация:
    20 окт 2008
    Сообщения:
    277
    Симпатии:
    0
    Вот еще всплыл случай необходимости использования.

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

    On Error Resume Next
    Err = 0
    mdoc.Save True, False
    If Err Then
    Print {...}
    End If
    On Error Goto errorproc
     
  11. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    ага, я на сохранение дока тож вешаю, но иначе
    Код (Text):
    On Error Resume Next
    if not(mdoc.Save(True, False)) then
    If Err <> 0 Then
    ...
    end if
    end if
    On Error Goto errorproc
    потому как ошибка бывает не только на 32К, а и прав может не хватить и вообще, сохранение штука вредная
    правда, если док не новый, и фактически не был изменен, то Save вернет False, поэтому дополнительная проверка на код ошибки не мешает...
     
  12. VladSh

    VladSh начинающий
    Lotus team

    Регистрация:
    11 дек 2009
    Сообщения:
    1.251
    Симпатии:
    2
    На собственном опыте убедился, что если можно (а оно можно, если постараться), то лучше обойтись без On Error Resume Next.
    Был в шоке, когда в вызываемой процедуре для GetDocumentByUNID указал On Error Resume Next, но обработчик ошибок вызывающей процедуры выдал мне Err = 4091! Это было... точно не помню, вроде в фоновых агентах. Стали ставить принудительно Err = 0, но в некоторых особо хитрых случаях (не помню - здесь вы мне можете или верить или не верить) не работало и это!
    Пришли к тому, что лучше использовать культурный метод для обнуления ошибки On Error Goto 0.
    Применительно к GetDocumentByUNID это выглядит так:
    Код (Text):
    Function GetNDbyUNID(NDB As NotesDatabase, UNID As String, ND_Result As NotesDocument) As Boolean
    Set ND_Result = Nothing
    If NDB Is Nothing Then Exit Function

    On Error 4091 Goto Err4091
    Set ND_Result = NDB.GetDocumentByUNID(UNID)
    If Not ND_Result Is Nothing Then
    GetNDbyUNID = IsDocAccessed(ND_Result, True)    'Где-то здесь уже выкладывал эту функцию
    Else
    On Error Goto 0                             'Собственно оно и есть
    End If

    Exit Function

    Err4091:
    Resume Next                                     '"Финт ушами"
    End Function
    Но это если мы хотим использовать одну и ту же функцию в любых случаях.
    Если не запариваться на повторность кода, то можно писать что хочешь и как хочешь, - копипастить и в каждом случае производить отладку заново...
     
  13. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    горячо поддерживаю твоих коллег :)

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

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    и тебе тоже под коленку, ага

    очень интересно, что не срабатывало О.о еще было бы лучше знать наверняка глюк ли это нотеса/домино или в коде недочет...
    тоже сбрасываю ошибку с пом Err = 0.

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

    вообще, на очень интересный момент ты указал. спасибо :)
     
  15. VladSh

    VladSh начинающий
    Lotus team

    Регистрация:
    11 дек 2009
    Сообщения:
    1.251
    Симпатии:
    2
    Точно недочёт кода не мог быть! Так и было раньше написано в функции Err = 0, от того столько недоумения и вызывает иногда то, что отказывается работать, что столько лет пропахало без проблем..

    <!--QuoteBegin-"Help"+-->
    <span class="vbquote">("Help")</span><!--QuoteEBegin-->GoTo 0
    If errNumber is specified, specifies that when the error occurs, the error should be handled by the most recent general On Error statement that specifies no error number.
    If errNumber is omitted, no errors are handled in the current procedure.[/quote]Или здесь: http://web3.inttrust.ru/site/itforum.nsf/4...33;OpenDocument
    И чуток ниже там есть "How does On Error work?".
    Но эту штуку я первый раз увидел не в хелпе, а на форуме Интертраста несколько лет назад:
    http://web3.inttrust.ru/site/itforum.nsf/4...33;OpenDocument

    Это верно.
    Что советуют, например, здесь: http://web3.inttrust.ru/site/itforum.nsf/4...33;OpenDocument
    не работает. Нужно сначала уйти на метку (у меня это Err4091 (отредактировал)), а с неё уже Resume Next, а потом чтобы перед выходом из функции обязательно On Error Goto 0, - тогда всё тип-топ! :)

    Не за что; всегда рад ;)
     
  16. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Можешь напомнить, как выглядела твоя GetDocByUNID/аналог или как ты удаляешь файлы с помошью Kill, например?
     
  17. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    VladSh
    проверил, можешь и сам проверить :)

    Код (Text):
        On Error Resume next
    Error 1000, "Error 1"
    On Error GoTo 0
    If Err <> 0 Then
    MsgBox "Error: " & Error & " = " & CStr(err)
    End If
    или я не так понял? :)

    Добавлено:
    это означает лишь, что все ошибки передаются в вызывающую процедуру, или в стандартный обработчик Notes, если стек вызовов пуст (надеюсь понятно выразился, бо может фраза и не совсем корректна)
     
  18. VladSh

    VladSh начинающий
    Lotus team

    Регистрация:
    11 дек 2009
    Сообщения:
    1.251
    Симпатии:
    2
    Akupaka, не, так не будет работать я чуть выше на этом специально остановился.

    В том-то и дело, что у меня при Err = 0 ошибки в некоторых случаях передавались вверх, а после On Error Goto 0 перестали.
     
  19. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    ага, вероятно, что я таки не так понял
    напиши, пож, свой пример полной обработки кода, чтобы можно было оценить наглядно, а не догадками? :)


    Добавлено:
    О.О интересно, никогда не встречал, и не слышал
     
  20. VladSh

    VladSh начинающий
    Lotus team

    Регистрация:
    11 дек 2009
    Сообщения:
    1.251
    Симпатии:
    2
    Akupaka, дык вот жи он: коммент 12.

    Добавлено:
    После
    Код (Text):
    Err4091:
    Resume Next
    Err уже = 0 (поэтому я там на Nothing проверяю), но если не поставить там On Error Goto 0, то в вызывающей проце обработчик в каких-то специфических случаях казал эту ошибку, т.е. On Error Goto 0 обязателен для корректного "подавления" :)
     
Загрузка...

Поделиться этой страницей