01.02.2008, 17:11 | #1 |
Участник
|
Ax3 KR2 COM: Получение человеческих сообщений об ошибках
Я работаю с ADSI при помощи COM.
В некоторых случаях возникает ошибка: Метод 'SetInfo' в COM-объекте класса '<неизвестно>' возвратил код ошибки 0x8007200A (<неизвестно>), который означает: <неизвестно>. Если обработать ошибку вот таким образом: X++: void setInfo() { COMError errorCom; ; try { object.SetInfo(); } catch (Exception::Error) { errorCom = object.error(); if (errorCom) throw error(strFmt("Ошибка %1 ('%2')", errorCom.number(), WinApi::formatMessage(errorCom.number()))); else throw Exception::Error; } } Ошибка становится человеческой: Ошибка -2147016694 ('Указанное значение или атрибут службы каталогов не существует.') Но при этом мы обязаны знать, какой объект зашибся. Я пробовал обработать эту штуку глобально, но вместо errorCom.number() использовать WinApi::GetLastError, но оказалось, что она возвращает 0 всегда в таки случаях. Как сделать так, чтобы
|
|
|
За это сообщение автора поблагодарили: axaLearner (1). |
07.03.2008, 13:16 | #2 |
Developer
|
Можно в Info.Add() редактировать добавляемую строку. Оттуда же брать код ошибки. Только придется анализировать стек вызова (искать \classes\com).
Криво, но хоть как-то работает. |
|
07.03.2008, 16:08 | #3 |
Участник
|
Ну, я просто написал класс-обертку для обращений к COM. Соответственно, любое обращение в этом классе оборачивается в try...catch и я всегда знаю какой объект ошибся.
По аналогии со многими классами Axapta. Начиная от CCADO... и кончая ComOfficeDocument_RU. В большинстве случаев, этого достаточно. А если все-таки возникает необходимость напрямую обращаться к методам COM-объекта, не через класс-обертку, то тут сам смотришь, оправдано ли try...catch или нет. |
|
08.04.2008, 18:01 | #4 |
Участник
|
|
|
09.04.2008, 12:28 | #5 |
Участник
|
Ни разу не разбирал класс ComOfficeDocument_RU ? С Excel или Word из Axapta не работал?
Идея заключается в том, что ты, конечно, можешь какждый раз в теле программы писать нечто вроде X++: COM comObject; comObject = new COM('MyCom'); comObject.method(); X++: MyClassForCom myClassForCom;
myClassForCom = new MyClassForCom();
myClassForCom.method(); |
|
17.04.2008, 17:56 | #6 |
Участник
|
а как подавить вывод этого сообщения от ком-объекта? даже после перехвата в try-catch оно всё равно выводится.
__________________
Felix nihil admirari |
|
17.04.2008, 18:56 | #7 |
Участник
|
Цитата:
Спокуха ! Зачем так раздражаться ? Работал с COM. Вопрос был связан с тем как обертку try Catch сделал. По идее если есть внешняя обертка - вложенный try Catch и транзакции то может и не сработать. Интересно можно ли это обойти. Т.е. заставить гарантировано выдавать корректное сообщение об ошибке. |
|
17.04.2008, 18:56 | #8 |
Участник
|
|
|
18.04.2008, 11:46 | #9 |
Участник
|
Цитата:
Внешний Try...Catch - никак не мешает вложенному Try...Catch. Перехватывает ошибку всегда ближайший try...catch. Если надо "передать" исключение на предыдущий уровень, то просто после try..Catch генеришь исключение throw error("Ошибка") или возвращаешь "пустое" (ошибочное) значение, которое обрабатывается во внешнем методе. А вот транзакция действительно мешает. Но тут ничего не поделаешь. Вне зависимости от того, кто именно сгенерил ошибку - COM или внутренний объект Axapta. При любом раскладе произойдет вылет в try...catch ближайший к началу транзакции самого верхнего уровня. |
|
18.04.2008, 11:51 | #10 |
Участник
|
Цитата:
Однако можно ведь и не доводить до сообщений об ошибках. Как правило, существует методы предварительной проверки: а сможет ли данный метод выполниться успешно? Если "Да", то запускаем метод, если "Нет", то запускать его не имеет смысла, поскольку он сгенерит исключение. Ну, например, если в файле Excel нет 2-го листа, то попытка что-то ввести на второй лист сгенерит исключение. Но ведь можно заранее узнать у файла Excel сколько листов он имеет и при попытке обратится на заведомо не существующий лист выдавать предупреждение. |
|