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

Тема в разделе "Lotus - Программирование", создана пользователем Akupaka, 31 май 2010.

Наш партнер Genesis Hackspace
  1. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.363
    Симпатии:
    2
    Всем привет.

    Пытаюсь тут наваять принципы обработки ошибок и обработчики поинтереснее придумать под LS.
    Возник вопрос, а можно ли определить, что ошибка возникла в текущей процедуре, а не в вызванной из нее?
    Понятно, что можно для каждой вызываемой процедуры объявить свой обработчик, ну, а без такового можно?

    Кому интересно, из практики:
    - результат функции не инициализируется, если в ней возникла необработанная исключительная ситуация, даже, если перед ее возникновением этот результат был назначен.
    Т.е.:
    Код (LotusScript):
    Function F1() As Variant
    F1 = False
    Error 1000, "Some error"
    End Function

    Sub Initialize()
    ' так использовать нельзя
    On Error Resume Next
    If F1() Then
    Msgbox "F1 returned True"
    End If

    ' так лучше
    Dim F1Res as Variant
    On Error Resume Next
    F1Res = F1()
    If F1Res Then
    Msgbox "F1 returned True"
    End If

    ' причем, если F1Res используется для возврата значений нескольких функций, то перед вызовом функции ее (F1Res) необходимо сбрасывать!
    Dim F2Res as Variant
    On Error Resume Next
    F2Res = True
    F2Res = F1() ' F1() не вернула результат, но и не сбросила состояние F2Res!!! F2Res == True из предыдущего состояния
    If F2Res Then
    ' ЭТОТ код выполнится ошибочно
    Msgbox "F1 returned True"
    End If
    End Sub
    Для решения этой проблемы, нужно иметь в функции обязательный обработчик, в котором происходит инициализация возвращаемого значения, при этом, ошибку необходимо передавать либо в результате, либо в иной структуре (возвращаемый параметр, глобальная переменная/объект).
     
  2. ToxaRat

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

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.109
    Симпатии:
    19
    юзай GetThreadInfo
    Код (LotusScript):
    Code    Meaning
    LSI_THREAD_LINE Current Line Number
    LSI_THREAD_PROC Name of current procedure
    LSI_THREAD_MODULE   Name of current module
    LSI_THREAD_VERSION  LotusScript version number
    LSI_THREAD_LANGUAGE (Human) language setting
    LSI_THREAD_COUNTRY  Country or region setting
    LSI_THREAD_TICKS    Get current clock ticks
    LSI_THREAD_TICKS_PER_SEC    Get clock ticks per second (supported only on platforms that support parallel processing primitives)
    LSI_THREAD_PROCESS_ID   Get current process ID (supported only on platforms that support parallel processing primitives)
    LSI_THREAD_TASK_ID  Get current task ID (supported only on platforms that support parallel processing primitives)
    LSI_THREAD_CALLPROC Get the name of the calling procedure
    LSI_THREAD_CALLMODULE   Get the name of the calling module
    для обработки ошибок самое оно
     
  3. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.363
    Симпатии:
    2
    Когда-то я хотел на нем построить трассировку вызовов, но почему-то на каком-то из вызовов нотес падал. Есть объяснение?
     
  4. nvyush

    nvyush Well-Known Member
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Если лень объявлять обработчики в вызываемых процедурах, то можно, конечно, и такое сваять:
    Я предпочитаю объявлять обработчики ошибок явно во всех вызываемых процедурах/функциях в стиле http://www.ferdychristant.com/blog//articles/DOMM-6BPT8R
    P.S. Ни разу не удалось трассировкой вызовов уронить Лотус.
     
  5. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.363
    Симпатии:
    2
    Може я особенный? :) На каком-то из N-уровней вложенности у меня стабильно валился клиент. Был какой-то из 6/7 нотесов.
    Спасибо за статью!
     
  6. nvyush

    nvyush Well-Known Member
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Где-то натыкался на информацию, что недокументированная функция Lsi_info не является thread-safe, т.е. если её дёргают несколько потоков, то можно уронить клиента/сервера. Особенно актуально для сервера. Поэтому лучше использовать GetThreadInfo.

    P.S. Тут обсуждалось: http://www-10.lotus.com/ldd/nd6forum.nsf/C...3c?OpenDocument
     
  7. Omh

    Omh Well-Known Member
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Я поступаю так же как nvy, обработчик ошибок в каждой процедуре/ф-ии локальный (т.е. не возвращает ошибку наверх).
     
  8. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    и рыпку съесть и .... :)
    хочеца одновременно и значение вернуть и исключение бросить? так не бывает :)
    про getthreadinfo: можно смело использовать константы, объявленные в хелпе.
    по теме есть классика от A. Guirard: http://www.ibm.com/developerworks/lotus/li...gLS2/index.html
    Еще один вариант хэндлера попадался недавно в шаблоне discussion 8.5. (lslib)lsClassException.
     
  9. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.363
    Симпатии:
    2
    А он разве так делает? :) Если он делает так же как в статье, то там обработка ошибок поднимается наверх, но с трейсом.

    nvy
    Если я правильно помню, то я записывал значения из GetThreadInfo (но не помню точно или из LSI_info) в свой массив! Т.е. не так как в статье.
    Так как в статье я тоже делаю обычно, только по-своему группирую. Но в случае с функциями так делать нельзя, почему писал выше.

    Добавлено:
    Бывает, но надо немного допилить :) т.е. исключение "поднять" в вызывающей функции. Т.е. как в лотусе часто бывает - через жп.
     
  10. nvyush

    nvyush Well-Known Member
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Не, я поступаю не так. В библиотеках обработчик ошибки возвращает ошибку наверх, а вот в кнопках и событиях ошибки обрабатываются и логируются. В результате всегда (почти) можно посмотреть, откуда у ошибки "ноги растут".

    Добавлено:
    При возникновении ошибки в функции возможны два подхода. Либо функция генерит ошибку и не возвращает ничего вразумительного, либо внутри себя сбрасывает ошибку и возвращает Null, Nothing, Empty, False и т.д. Это к вопросу об использовании конструкцци On Error Resume Next — её использование оправдано в исключительных случаях (и побольшей части из-за лени программиста нормально обработать ошибки).
     
  11. Omh

    Omh Well-Known Member
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Ну, значит, так как nvy, но ошибку наверх не возвращаю.
    Другими словами, не так :) :)

    Чёт я слажал немного :)
    Смотрю в книгу, вижу фигу.
     
  12. Medevic

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

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Да можно и ошибку вернуть и значение. Только зачем?
     
  13. Omh

    Omh Well-Known Member
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
  14. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Это не через жп. Это подход, принятый в цивилизованных языках, поддерживающих исключения. Если функция бросила исключение - она не возвращает результата. Грубо говоря - она возвращает объект исключения.
    Ниче не понимаю... Если функция бросает исключение - она ничего не возвращает. Или не так? Можно конечно по сишной традиции возвращать код ошибки, а значение возвращать через входной параметр функции. Но речь вроде идет именно об исключениях?
     
  15. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.363
    Симпатии:
    2
    Да? Значит я думаю через жп ))
     
  16. Мыш

    Мыш Well-Known Member
    Lotus team

    Регистрация:
    12 фев 2008
    Сообщения:
    1.038
    Симпатии:
    9
    А если ошибка возникает уже в обработчике ошибки? Скажем, обработчик уже произошедшей ошибки хочет отправить сообщение по почте, создать документ в базе, зачистить какие-то файлы на уровне ОС и т.п. - и вновь вызывает ошибку. Я в таких случаях пишу "... resume next"...
     
  17. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Меня бы лично такое поведение(значение + exception) повергло в шок:
    Пользователь: Компьютер, скока будет дважды два?
    Компьютер: Четыре, и, кстати, у тебя канал до сервера отвалился!
    Как документировать такую функцию: всегда возвращает верное значение, но иногда при этом бросает ошибку?
    Очевидно напрашивается разделение функции на две, каждая из которых будет занимаца своим делом.
     
  18. Medevic

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

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Исключение мы обработаем внутри. Но с помощью Err можно узнать номер ошибки после выхода из функции. И при желании вызвать еще одно исключение.
    Короче, пример. В результате получим и 5, и обработаем ошибку.
    Код (Text):
    Sub test
    On Error Goto e
    Msgbox(Cstr(errtest))
    If Err Then Error Err
    Exit Sub
    e:
    Msgbox Error
    Resume
    End Sub

    Function errtest As Long
    On Error Goto e
    Dim a As Long, b As Long
    b = 1
    errtest = 5
    errtest = b / 0
    Exit Function
    e:
    Exit Function
    End Function
     
  19. Мыш

    Мыш Well-Known Member
    Lotus team

    Регистрация:
    12 фев 2008
    Сообщения:
    1.038
    Симпатии:
    9
    А какая польза-то от этой пятерки? Она же не есть правильное значение, полученное в результате выполнения функции. Хотя если использовать возвращаемое значение как нумератор строк кода... ;)
     
  20. Medevic

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

    Регистрация:
    10 дек 2004
    Сообщения:
    3.346
    Симпатии:
    2
    Да хз. Я таким не пользуюсь. :)
     
Загрузка...

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