Централизованная обработка ошибок в VB6 - PullRequest
4 голосов
/ 30 марта 2010

У меня есть следующий метод, который вызывают все обработчики ошибок:

Public Function ToError(strClass As String, strMethod As String) As String

    On Error GoTo errHandle

    ToError = "Err " & Err.Number & _
                      ", Src: " & Err.Source & _
                      ", Dsc: " & Err.Description & _
                      ", Project: " & App.Title & _
                      ", Class: " & strClass & _
                      ", Method: " & strMethod & _
                      ", Line: " & Erl

    Err.Clear

exitPoint:
   Exit Function

errHandle:
   oLog.AddToLog "Error in ToError Method: " & Err.Description, False
   Resume exitPoint
End Function

Оказывается, потому что я объявляю обработчик ошибок в этой функции On Error GoTo errHandle, VB6 очищает ошибку, прежде чем я смог ее записать.

Есть ли способ предотвратить очистку ошибки оператором On Error GoTo errHandle?

Ответы [ 4 ]

6 голосов
/ 30 марта 2010

Оператор On Error всегда очищает переменную Err (Erl также сбрасывается в 0). Теоретически это означает, что вы можете решить проблему, переместив оператор On Error ниже строки ToString = ... (или вообще убрав обработчик ошибок в функции ToError), но, к сожалению, это не всегда будет работать.

Каждый компонент (DLL, ActiveX EXE и т. Д.), На который ссылается ваш проект, по существу получает свой собственный экземпляр Err в памяти. Итак, если ваш MainApp.exe вызывает ошибку, которая передается в ToError (например, в отдельном ErrorHandling.dll), DLL не увидит переменную Err, которую видит ваш EXE. Каждый из них имеет свои собственные Err переменные.

Есть как минимум два пути решения проблемы, о которых я могу подумать:

Метод 1

Как упоминает Zian Choy , вы можете добавить дополнительные параметры к вашей ToError функции, по одному для каждого свойства объекта Err, к которому вам нужен доступ.

Код

Public Function ToError( _
   ByVal strErrSource As String, _
   ByVal nErrNumber As Long, _
   ByVal sErrDescription As String, _
   ByVal nLineNumber As Long) As String

Пример использования

Затем вам нужно будет так вызывать ваши обработчики ошибок, передавая ему все соответствующие значения из текущего объекта Err вместе с Erl:

ToError Err.Source, Err.Number, Err.Description, Erl 

Если вы также хотите App.Title, вам придется добавить дополнительный параметр к ToError для этого, так как App.Title будет равен App.Title проекта, где ToError Метод определен, а не компонент, где возникла ошибка. Это важно, если ToError находится в другом проекте.

Метод 2

Вы можете сделать свои ToError вызовы чуть менее многословными, передав сам объект Err в качестве параметра функции, однако первое, что ваша функция ToError должна сделать в этом случае, это немедленно сохранить копию все необходимые свойства, так как последующий оператор On Error очистит переменную.

Код

Public Function ToError(ByVal oError As ErrObject, ByVal nLineNumber As Long) As String

   'Copy the important Err properties first, '
   'before doing anything else...            '

   Dim strErrSource As String
   Dim nErrNumber As Long
   Dim strErrDescription As String

   strErrSource = oError.Source
   nErrNumber = oError.Number
   strErrDescription = oError.Description

   On Error Goto errHandle

   'More code here
   '...

Пример использования

ToError Err, Erl
2 голосов
/ 30 марта 2010

Вы можете решить проблему, передав значения объекта Err в ToError в качестве параметров.

1 голос
/ 30 марта 2010

Нет способа предотвратить On Error сброс ошибки.

  • Вы можете просто удалить обработку ошибок из ToError. Он такой короткий и мягкий, что вряд ли когда-нибудь возникнет ошибка.
  • Возможно, было бы лучше выполнить рефакторинг обработки ошибок, чтобы этот код ToError был встроен в процедуру сообщения об ошибках общего назначения, которая выполняет ведение журнала или все, что необходимо. Затем используйте приемы из ответа Майка .

Кстати, если кто-то читает это, добавляет свои обработчики ошибок вручную, остановите все, что вы делаете, и немедленно получите бесплатный пакет MZ-Tools .

0 голосов
/ 20 октября 2016

Вы можете создать пользовательский тип, как показано ниже

Private Type TempErrObj
    ErrNumber As Integer
    ErrSource As String
    ErrDescription As String
End Type

Позже измените функцию ToError, как показано ниже:

Public Function ToError() As String
    Dim iTempErr As TempErrObj
    iTempErr.ErrNumber = Err.Number
    iTempErr.ErrSource = Err.Number
    iTempErr.ErrDescription = Err.Description
    On Error GoTo errHandle

    ToError = "Err " & iTempErr.ErrNumber & _
                      ", Src: " & iTempErr.ErrSource & _
                      ", Dsc: " & iTempErr.ErrDescription & _
                      ", Project: " & App.Title & _
                      ", Line: " & Erl
    Err.Clear

exitPoint:
   Exit Function

errHandle:
    oLog.AddToLog "Error in ToError Method: " & Err.Description, False
   Resume exitPoint
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...