Archived

This forum has been archived. Please start a new discussion on GitHub.

why client cannot catch user-defined exception in AMI mode?

I define an interface :

interface myI {
["ami"] int myOP(string s) throw myEx ;
}


but I just find ice_exception(const ::Ice::Exception&)

How could I catch "myEx" in callback object?

Why not ice_exception(const myEx&)??

my env : c++ , Ice-2.1.0 , linux

many thanks !

Comments

  • marc
    marc Florida
    All exceptions are derived from Ice::Exception, including your own user exceptions. In your implementation of ice_exception(), you can down-cast the exception to your derived type to both check whether the exception that is raised is indeed your user exception, as well as to get the actual value of your exception. An alternative implementation is to re-throw the exception in ice_exception() with ex->ice_throw(), and then to use a catch() for your user exception.
  • marc
    marc Florida
    By the way, Ice 2.1.0 is quite old. I highly recommend to upgrade.
  • ice_throw does not work
    marc wrote: »
    All exceptions are derived from Ice::Exception, including your own user exceptions. In your implementation of ice_exception(), you can down-cast the exception to your derived type to both check whether the exception that is raised is indeed your user exception, as well as to get the actual value of your exception. An alternative implementation is to re-throw the exception in ice_exception() with ex->ice_throw(), and then to use a catch() for your user exception.

    I re-throw the exception with ex->ice_throw.

    try{
    ex->ice_throw();
    }
    catch(myEx e)
    {
    //go to bed
    }
    catch(::Ice::Exception e)
    {
    //watch TV
    }

    I have never gone to bed ....

    can you give a sample code ?
  • benoit
    benoit Rennes, France
    Hi,

    This should work. Try for example to modify the client from the demo/Ice/async demo (available in Ice 3.2.0). Change the implementation of the AMI callback ice_exception method to:
        virtual void ice_exception(const Ice::Exception& ex)
        {
            try
            {
                ex.ice_throw();
            }
            catch(const RequestCanceledException&)
            {
                cerr << "request failed!" << endl;
            }
            catch(const Ice::Exception& ex)
            {
                cerr << "sayHello AMI call failed:\n" << ex << endl;
            }
        }
    

    Then run the client against the server and type "d" followed by "s" to shutdown server and get it to cancel the delayed request. You'll see that the exception is correctly catch by the client and the client will display "request failed!".

    Also, note that you should catch exceptions by reference not value, so your code should look like the following:
    try{
    ex.ice_throw();
    }
    catch(const myEx& e)
    {
    //go to bed
    }
    catch(const ::Ice::Exception& e)
    {
    //watch TV
    }
    

    Cheers,
    Benoit.