Table of Contents Previous Next
Logo
Client-Side Slice-to-C++ Mapping : 6.13 Exception Handling
Copyright © 2003-2009 ZeroC, Inc.

6.13 Exception Handling

Any operation invocation may throw a run-time exception (see Section 6.10 on page 216) and, if the operation has an exception specification, may also throw user exceptions (see Section 6.9 on page 212). Suppose we have the following simple interface:
exception Tantrum {
    string reason;
};

interface Child {
    void askToCleanUp() throws Tantrum;
};
Slice exceptions are thrown as C++ exceptions, so you can simply enclose one or more operation invocations in a trycatch block:
ChildPrx child = ...;           // Get proxy...
try {
    child>askToCleanUp();      // Give it a try...
} catch (const Tantrum& t) {
    cout << "The child says: " << t.reason << endl;
}
Typically, you will catch only a few exceptions of specific interest around an operation invocation; other exceptions, such as unexpected run-time errors, will typically be dealt with by exception handlers higher in the hierarchy. For example:
void run()
{
    ChildPrx child = ...;       // Get proxy...
    try {
        child>askToCleanUp();  // Give it a try...
    } catch (const Tantrum& t) {
        cout << "The child says: " << t.reason << endl;

        child>scold();         // Recover from error...
    }
    child>praise();            // Give positive feedback...
}

int
main(int argc, char* argv[])
{
    int status = 1;
    try {
        // ...
        run();
        // ...
        status = 0;
    } catch (const Ice::Exception& e) {
        cerr << "Unexpected runtime error: " << e << endl;
    }
    // ...
    return status;
}
This code handles a specific exception of local interest at the point of call and deals with other exceptions generically. (This is also the strategy we used for our first simple application in Chapter 3.)
For efficiency reasons, you should always catch exceptions by const reference. This permits the compiler to avoid calling the exception’s copy constructor (and, of course, prevents the exception from being sliced to a base type).

Exceptions and Out-Parameters

The Ice run time makes no guarantees about the state of out-parameters when an operation throws an exception: the parameter may have still have its original value or may have been changed by the operation’s implementation in the target object. In other words, for out-parameters, Ice provides the weak exception guarantee [21] but does not provide the strong exception guarantee.1

Exceptions and Return Values

For return values, C++ provides the guarantee that a variable receiving the return value of an operation will not be overwritten if an exception is thrown. (Of course, this guarantee holds only if you do not use the same variable as both an out-parameter and to receive the return value of an invocation (see page 231).)

1
This is done for reasons of efficiency: providing the strong exception guarantee would require more overhead than can be justified.

Table of Contents Previous Next
Logo