В прошлом шаге мы с Вами посмотрели как вообще обрабатываются ошибки в VB. Давайте попробуем применить наши знания к COM DLL. Мы возьмем тот же компонент, что и из шага "Шаг 39 - Понимание использования MTS". И изменим главный метод.
Public Function Method() As Boolean Dim context As ObjectContext Dim sql As ClassSQL Dim oracle As ClassORACLE Set context = GetObjectContext Set sql = context.CreateInstance("ProjectTransaction.ClassSQL") Set oracle = context.CreateInstance("ProjectTransaction.ClassORACLE") sql.Method oracle.Method Set sql = Nothing Set oracle = Nothing context.SetAbort Err.Raise 11111, "Com DLL", "Hello Client" Method = True End Function
Нужно заново собрать DLL и обновить в Transaction server. У клиента сделаем перехват ошибок:
Private Sub Command1_Click() On Error GoTo Errors: Dim a As ClassGeteral Dim b As Boolean Set a = New ClassGeteral b = a.Method Set a = Nothing If b = True Then MsgBox "Ok" Else: MsgBox "Error" End If Exit Sub Errors: MsgBox "Error detected" MsgBox (Str(Err.Number)) MsgBox (Err.Source) MsgBox (Err.Description) End Sub
Запустим и посмотрим.
Клиент перехватил ошибку и обработал, что и требовалось. Итак, если произошла ошибка нужно вернуть SetAbort. Только будьте внимательны, если ошибка внутри какого-то компонента, то код этой ошибки нужно передать по цепочке объектов, а клиент должен знать все коды, чтобы что-то сказать пользователю. Вызов SetAbort гарантирует, что дальнейшее обращение к объектам прекратится и ошибка будет отлавливаться. Внимательным нужно быть в плане того, что стандартный код подразумевает, что ошибки отлавливаются в каждом компоненте, и, если она внутри вызова, то может затеряться. Вы узнаете, что транзакция отменена, но почему не узнаете. Вариантов реализации много, может клиенту и не надо знать почему и что произошло, а только сам факт. Есть такая возможность и как сказано в уставе - умело орудуя штыком и прикладом...