VBA теряет описание пролетающей ошибки при late-bound вызове

Программирование на Visual Basic for Applications
tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

VBA теряет описание пролетающей ошибки при late-bound вызове

Сообщение tyomitch » 22.08.2007 (Ср) 13:31

Наблюдение: если метод, вызываемый внутри VBA-метода, генерирует ошибку, а сам VBA-метод вызван через IDispatch::Invoke своего класса, то Err.Description приходит пустым.

Если вызывать этот VBA-метод через интерфейс, то проблемы нет.
Если Err.Raise стоит непосредственно в VBA-методе, то проблемы тоже нет.

Сейчас пойду проверять, как с этим делом в VB6.
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 16:02

Похоже, что это не баг, а фича. (В VB6 вопроизвелось полностью.)

1. Вызов внешнего метода возращает неудачный HRESULT
2. Рантайм вызывает GetErrorInfo и ныкает полученные данные куда-то к себе
3. Рантайм видит, что обработчика ошибок не стоит, и готовится переслать ошибку выше, для чего вызывает SetErrorInfo с теми же данными
4. Рантайм перед выходом из VB-метода очищает все его переменные
5. В одной из них лежит объект с очень сложным деструктором, в котором происходит и обрабатывается ряд исключений.
6. После очистки переменных, данные о произошедшем исключении, записанные вызовом SetErrorInfo, оказываются стёртыми.
7. Теперь метод выходит с неудачным HRESULT
8. Dispatch-обёртка внутри рантайма вызывает GetErrorInfo, обламывается, и оставляет ExcepInfo пустым


Видимо, это сделано затем, чтобы ошибка изнутри деструктора объекта, удаляемого по другой ошибке (double-fault), перезаписывала ExcepInfo своими данными, и тем самым вызвавшая сторона получала бы информацию о последней возникшей ошибке.
Изображение

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.08.2007 (Ср) 16:07

А параметр Error Trapping в настройках на это поведение не влияет?
Lasciate ogni speranza, voi ch'entrate.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 16:12

Даже не может влиять: проверялось со скомпилированным VB6-кодом.


С ранним связыванием, насколько я понял, данные не теряются потому, что VB их достаёт из своей нычки, а не из GetErrorInfo.
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 19:21

В итоге для обхода этой фичи пришлось содержимое того очень сложного деструктора обернуть в вызов GetErrorInfo(ei) ... SetErrorInfo(ei) -- так что любые ошибки, возникшие теперь внутри деструктора, проглотятся.
Решили, что терять их менее обломно, чем терять все ошибки в процедурах, использующих этот класс с очень сложным деструктором.
Изображение


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 63

    TopList