Orber (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);
};

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

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

Но при вызове через Erlang - получаю -

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

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

Редактировать. Вот как я вызываю сервер из erlang.

В приглашении 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 

person spkhaira    schedule 24.12.2015    source источник
comment
Как вы звоните на сервер из орбера?   -  person Steve Vinoski    schedule 24.12.2015
comment
Обновленный вопрос с этой информацией   -  person spkhaira    schedule 24.12.2015


Ответы (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, хотя редко, если вообще когда-либо требуется в C++ ORB, связана с некоторой гибкостью спецификации CORBA, а также с традициями разработки C++ ORB. исходная спецификация CORBA частично была компромиссом между статическим и динамическим языковыми лагерями. Сторонники динамического подхода настаивали на том, чтобы IFR был в спецификации, поскольку он нужен им для извлечения информации о типе во время выполнения (и, очевидно, они выполнили свое желание, поскольку он всегда был частью CORBA), но сторонники статического анализа полагали, что IFR не нужен, поскольку все необходимая информация о типе может быть закодирована в коде C/C++, сгенерированном из определений IDL. Сообщество разработчиков C++ ORB традиционно придерживалось подхода генерации кода и рассматривало IFR как необязательный компонент среды выполнения, а C++ ORB, используемые в этом вопросе, извлекают информацию об определяемом пользователем исключении cirrus_error из сгенерированных заглушек и скелетов. Но ORB, написанные на других языках, таких как Smalltalk и Erlang, решили использовать IFR в качестве обычного компонента среды выполнения ORB, и поэтому они требуют регистрации информации о типе в IFR, чтобы она была доступна для среды выполнения ORB. . Тем не менее, в Erlang определенно было бы возможно генерировать информацию об определенных пользователем исключениях в заглушки/скелеты и получать ее оттуда во время выполнения.

person Steve Vinoski    schedule 24.12.2015
comment
Отлично, это работает. Большое спасибо, Стив. Насколько я понимаю, почему мне не нужен такой шаг при вызове сервера C++ через клиент C++? - person spkhaira; 24.12.2015