[omniORB] Narrowing DII exception - take 2
Kevin Bailey
ke-omniorb@retriever.dyndns.org
Mon, 30 Jul 2001 11:09:04 -0700
I'm still trying to find the right way to propagate a user exception
through a DII request. I suspect the included example is closer to
the correct way than before but it still translates all user exceptions
to CORBA::MARSHAL.
It can't even narrow the exception to an UnknownUserException.
This implies that the exception is a genuine CORBA::MARSHAL and
that either the unmarshalling of user exceptions has a bug or
that I'm supposed to configure the DII request to accept an
exception of that type prior to the evocation. I can't find
any way to do the latter, however.
Can someone at least tell me if this is the correct way ?
If it is, is this a known bug ? I haven't found anything
mentioning it in the archives.
// pingtest.cc
#include "pingable.hh"
#include <iostream>
class Pingable_i:
public POA_Fruit::Pingable
{
public:
virtual void Ping();
};
bool ping_should_throw;
void Pingable_i::Ping()
{
std::cout << "Pingable_i::Ping" << std::endl;
if (ping_should_throw)
throw Fruit::MyUserException();
}
void DII_Evoke(Fruit::Pingable_ptr r_pingable)
{
CORBA::Request_var r_request = r_pingable->_request("Ping");
r_request->invoke();
try
{
CORBA::Exception* p_ex;
p_ex = r_request->env()->exception();
if (p_ex)
{
std::cout << "Caught exception" << std::endl;
CORBA::UnknownUserException* p_un_ex;
p_un_ex = CORBA::UnknownUserException::_downcast(p_ex);
if (p_un_ex)
{
std::cout << "Narrowed to UnknownUserException" << std::endl;
const Fruit::MyUserException* p_my_ex;
if (p_un_ex->exception() >>= p_my_ex)
{
std::cout << "Extracted Fruit::MyUserException" << std::endl;
const_cast<Fruit::MyUserException*>(p_my_ex)->_raise();
}
}
p_ex->_raise();
}
}
catch (CORBA::MARSHAL&)
{
std::cout << "Caught CORBA::MARSHAL" << std::endl;
}
catch (Fruit::MyUserException&)
{
std::cout << "Caught Fruit::MyUserException" << std::endl;
}
}
int main(int argc, char* argv[])
{
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "omniORB3");
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();
Pingable_i* p_ping = new Pingable_i();
Fruit::Pingable_var r_pingable = p_ping->_this();
// Try once to make sure that the call is ok
ping_should_throw = false;
DII_Evoke(r_pingable);
// Have it throw a user exception
ping_should_throw = true;
DII_Evoke(r_pingable);
orb->destroy();
return 0;
}
// pingable.idl
module Fruit
{
exception MyUserException
{
};
interface Pingable
{
void Ping()
raises(MyUserException);
};
};