Орбер (Erlang ORB) не может перехватить определенные пользователем исключения при выдаче с помощью TAO orb

У меня есть C++ CORBA-сервер, который реализует интерфейс, выбрасывающий пользовательское исключение.

Я легко могу поймать конкретное исключение, когда клиент и сервер реализованы на C++ (протестировано с использованием TAO orb и omniORB).

Но когда я вызываю тот же метод из Erlang (используя orber), исключение появляется как общее исключение, а не как определенное пользователем исключение.

Чтобы проверить это, я просто использовал простой IDL -

interface Messenger {

    exception cirrus_error{
            short error_code;
            string error_desc;
    };

    boolean send_message(in string user_name,
                       in string subject,
                       inout string message) raises (cirrus_error);
};

Если и сервер, и клиент находятся в C++, я получаю исключение (для тестирования я его кодировал, чтобы всегда выдавать пользовательское исключение)

CORBA exception: cirrus_error (IDL:Messenger/cirrus_error:1.0)

Но когда вызывается через Erlang - я получаю -

** exception throw: {'EXCEPTION',{'UNKNOWN',[],1330446337,'COMPLETED_MAYBE'}}
 in function  corba:raise/1

Нужно ли делать что-то особенное при заявлении приложения Orber, чтобы включить правильное поведение?

Edit - это то, как я называю сервер из Erlang -

По подсказке Эрланга, это то, что я делаю -

1> orber:jump_start().

2> O = corba:string_to_object(IORStr).

3> 'Messenger':send_message(O, "s", "t", "f").
** exception throw: {'EXCEPTION',{'UNKNOWN',[],1330446337,'COMPLETED_MAYBE'}}
     in function  corba:raise/1 

1 ответ

Решение

Вам нужно зарегистрировать ваши определения IDL в репозитории интерфейса orber (IFR) перед вызовом метода. Если ваш файл IDL назван messenger.idlнапример, его компиляция создает oe_messenger.erl, который обеспечивает oe_register/0 функция. Вызов этого регистрирует информацию о вашем определяемом пользователем исключении в IFR, который использует декодирование CDR orber, чтобы иметь возможность правильно декодировать любые ответы, содержащие это исключение:

1> orber:jump_start().
...
2> ic:gen(messenger).
Erlang IDL compiler version 4.4
ok
3> make:all().
Recompile: Messenger
Recompile: Messenger_cirrus_error
Recompile: oe_messenger
oe_messenger.erl:65: Warning: function oe_get_top_module/4 is unused
oe_messenger.erl:91: Warning: function oe_destroy_if_empty/2 is unused
up_to_date
4> oe_messenger:oe_register().
ok
5> M = corba:string_to_object(IORStr).
...
6> 'Messenger':send_message(M, "a", "b", "c").
** exception throw: {'EXCEPTION',{'Messenger_cirrus_error',"IDL:Messenger/cirrus_error:1.0",
                                                           1234,"yep, an error"}}
     in function  corba:raise/1 (corba.erl, line 646)

Обновление: Причина, по которой этот дополнительный шаг регистрации IFR необходим в orber, хотя редко, если вообще требуется в ORB C++, обусловлена ​​некоторой гибкостью спецификации CORBA, а также традициями разработки ORB C++. Первоначальная спецификация CORBA была частично компромиссом между статическими и динамическими языковыми лагерями. Динамический лагерь настаивал на том, чтобы IFR была в спецификации, так как они нуждались в ней для получения информации о типе во время выполнения (и, очевидно, они получили свое желание, поскольку она всегда была частью CORBA), но статический лагерь предполагал, что IFR не требуется, поскольку все необходимая информация о типе может быть закодирована в коде C/C++, сгенерированном из определений IDL. Сообщество разработчиков C++ ORB традиционно следовало подходу генерации кода и рассматривало IFR как необязательный компонент времени выполнения, а ORB C++, используемые в этом вопросе, извлекали информацию о пользовательских cirrus_error исключение из сгенерированных заглушек и скелетов. Но ORB, написанные на других языках, таких как Smalltalk и Erlang, решили использовать IFR в качестве обычного компонента среды выполнения ORB, и поэтому им требуется регистрация информации о типе в IFR, чтобы она была доступна для среды выполнения ORB., Тем не менее, в Erlang было бы возможно сгенерировать информацию о пользовательских исключениях в заглушки / скелеты и заставить среду выполнения извлечь ее оттуда.

Другие вопросы по тегам