Гость
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Обработка ошибок при вызове процедуры из процедуры / 6 сообщений из 6, страница 1 из 1
27.01.2018, 16:04
    #39592183
Wipeout2097
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок при вызове процедуры из процедуры
Народ, доброго всем времени суток! Понимаю, тема скорее всего изъезженная, но чего-то то ли я не могу нормальный контекст в поиске забить, то ли может я чего не догоняю... Вобщем, запускается процедура. В ней написан обработчик ошибок: On Error Go To, выход, метки и т.д. Из этой процедуры запускается вторая процедура. В ней тоже есть свой собственный обработчик ошибок. Вопрос: при срабатывании ошибки во второй процедуре, обработчик отрабатывает из первой процедуры... Помню, кажется, Саныч говорил, что Акс так делает то ли всегда, то ли по умолчанию... А всегда ли? Нет вариантов сделать так, что если ошибка в первой процедуре, то срабатывает ее обработчик, если во второй, то, соответственно, обработчик второй?
...
Рейтинг: 0 / 0
28.01.2018, 06:16
    #39592289
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок при вызове процедуры из процедуры
Я давно использую 2 типа обработчиков - обычный, который всегда срабатывает в текущей процедуре и всплывающий, который регистрирует ошибку в текущей процедуре и передает ее в вызвавшую процедуру, т.е. на верхнем уровне мы получаем сообщение об ошибке со стеком вызовов. Обычный обработчик ставится в процедурах верхнего уровня, которые непосредственно взаимодействуют с пользователем, а всплывающие - в модулях и классах.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
Sub NormalErrors()

    On Error GoTo ErrorHandler


ExitHere:
    On Error Resume Next
    Exit Sub
    Resume '>> remove in release
ErrorHandler:
    LogError Err.Number, Err.Description, Erl, "NormalErrors", "Module1"
    Resume ExitHere
End Sub

Sub BubbleError()

    On Error GoTo ErrorHandler

ExitHere:
    Exit Sub
    Resume '>> remove in release
ErrorHandler:
    Debug.Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
    Err.Raise Err.Number, "BubbleError of Module1", Err.Description & vbCrLf & "in BubbleError of Module1 at " & Erl
End Sub


Resume, который никогда не выполняется нужен для отладки, чтобы перейти на строку с ошибкой, Debug.Assert - чтобы при отладке ошибка не всплывала, а останавивалась в процедуре, где возникла. Эти строки удаляются в релизе. Есть еще пара типов обработчиков, но это уже детали
...
Рейтинг: 0 / 0
28.01.2018, 10:16
    #39592306
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок при вызове процедуры из процедуры
MrShin, это интересно
LogError -сохраняет лог в таблице, что такое Erl?
а какие ещё типы обработчиков применяете? (если это не ноу хау конечно)
...
Рейтинг: 0 / 0
29.01.2018, 07:48
    #39592572
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок при вызове процедуры из процедуры
Да, LogErr сохраняет ошибку в таблице и выводит ее на экран в виде сообщения, вот текст:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
'// module with error handling functions
    ' Purpose: Generic error handler.
    ' Logs errors to table "ErrorLog".
    ' Arguments: lngErrNumber - value of Err.Number
    ' strErrDescription - value of err.description
    ' strLine - code line number (Erl) Erl=0 if no row number in the line
    ' strCallingProc - name of sub|function that generated the error.
    ' strCallingModule - name of code module that generated the error.
    ' vParameters - optional string: List of parameters to record.
    ' bShowUser - optional boolean: If False, suppresses display.
Function LogError(ByVal lngErrNumber As Long, ByVal strErrDescription As String, strLine As String, _
                  strCallingProc As String, Optional strCallingModule As String, Optional vParameters = "{Missing}", Optional bShowUser As Boolean = True) As Boolean
    On Error GoTo Err_LogError
    Dim strMsg As String                              ' String for display in MsgBox
    Dim rst    As DAO.Recordset                       ' The Aph_tblErrorLog table
    Select Case lngErrNumber
        Case 0
            Debug.Print strCallingProc & " called error 0."
        Case 2501                                     ' Cancelled
            'Do nothing.
'        Case 3314, 2101, 2115                         ' Can't save.
'            If bShowUser Then
'                strMsg = "Record cannot be saved at this time." & vbCrLf & "Complete the entry, or press <Esc> to undo."
'                MsgBox strMsg, vbExclamation, "Error"
'            End If
        Case Else
            If bShowUser Then
                strMsg = "Error " & lngErrNumber & ": " & strErrDescription & vbCrLf & "in " & _
                strCallingProc & " of " & strCallingModule & " at " & strLine
                Interaction.MsgBox strMsg, vbExclamation, "Error " & Now()
            End If
            'log the error to database
            Set rst = CurrentDb.OpenRecordset("tbl_ErrorLog", , dbAppendOnly)
            rst.AddNew
            rst![ErrorNum] = lngErrNumber
            rst![ErrorDescription] = Left$(strErrDescription, 255)
            rst![ErrLine] = strLine
            rst![CallingProc] = strCallingProc
            rst![Module] = strCallingModule
            rst![CreatedTimeStamp] = Now()
            rst![UserName] = GetCurrentUserID()
            If Not IsMissing(vParameters) Then
                rst![Parameters] = Left(vParameters, 255)
            End If
            rst.Update
            rst.Close
            LogError = True
    End Select

Exit_LogError:
    Set rst = Nothing
    Exit Function
Err_LogError:
    strMsg = "An unexpected situation arose in your program." & vbCrLf & _
             "Please write down the following details:" & vbCrLf & vbCrLf & _
             "Calling Proc: " & strCallingProc & vbCrLf & _
             "Error Number " & lngErrNumber & " in line " & strLine & vbCrLf & strErrDescription & vbCrLf & vbCrLf & _
             "Unable to record because Error " & Err.Number & " in line " & Erl & vbCrLf & Err.Description
    Interaction.MsgBox strMsg, vbCritical, "LogError()"
    Resume Exit_LogError
End Function


Erl - это номер линии, Erl не равно нулю, только если строка с ошибкой пронумерована в коде, использую MZ-Tools для нумерации во всех модулях и в некоторых случаях свой использую нумератор на VBA, но MZ-Tools работает быстрее, в моем не все баги выловлены - если несколько раз добавить номера и убрать, кое-в каких местах нарушаются отступы, все не дойдут руки доделать.

Еще один полезный обработчик - всплывающий с финальным кодом:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Sub BubbleWithFinal()

    On Error GoTo ErrorHandler

ExitHere:
    On Error Resume Next

    'сюда помещаем код, который отрабатывает в любом случае, обычно закрытие рекордсетов и разрушение переменных

    Dim err_num As Long, err_descr As String, err_ln As String
    If Len(err_descr) > 0 Then GoTo ErrorRaise
    Exit Sub
    Resume '>> remove in release
ErrorHandler:
    err_num = Err.Number: err_descr = Err.Description: err_ln = Erl
    Debug.Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
    Resume ExitHere
ErrorRaise: On Error GoTo 0
    Err.Raise err_num, "BubbleWithFinal of Module1", err_descr & vbCrLf & "in BubbleWithFinal of Module1 at " & err_ln
End Sub


Есть еще модификации, но они уже заточены под конкретные приложения, идея в них та же.
Обработчики генерируются MZ-Tools одной кнопкой, очень удобно. Не ставлю обработчики только в самые простые процедуры типа возврата значения обычной переменной, в остальных, где принципиально может возникнуть ошибка, всегда ставлю обработчик.
...
Рейтинг: 0 / 0
29.01.2018, 07:53
    #39592573
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок при вызове процедуры из процедуры
Да, STOP_AT_ERROR и IS_DEV - просто глобальные булевские константы, первая включает остановку во всплывающих обработчиках, вторая - если True, то приложение в находится режиме разработки, используется не только в обработчиках, но и других местах кода для облегчения отладки. Выполнение не останавливается в любом случае, если IS_DEV = False.
...
Рейтинг: 0 / 0
29.01.2018, 08:47
    #39592589
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок при вызове процедуры из процедуры
MrShin,спасибо! попробую "всплывающий" использовать в коде. (про Erl не знал=забыл)
...
Рейтинг: 0 / 0
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Обработка ошибок при вызове процедуры из процедуры / 6 сообщений из 6, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]