In addition to any user exceptions that are listed in an operation's exception specification, an operation can also throw Ice run-time exceptions. Run-time exceptions are predefined exceptions that indicate platform-related run-time errors. For example, if a networking error interrupts communication between client and server, the client is informed of this by a run-time exception, such as ConnectTimeoutException
or SocketException
.
The exception specification of an operation must not list any run-time exceptions. (It is understood that all operations can raise run-time exceptions and you are not allowed to restate that.)
On this page:
Inheritance Hierarchy for Exceptions
All the Ice run-time and user exceptions are arranged in an inheritance hierarchy, as shown below:
Inheritance structure for exceptions.
Ice::Exception
is at the root of the inheritance hierarchy. Derived from that are the (abstract) types Ice::LocalException
and Ice::UserException
. In turn, all run-time exceptions are derived from Ice::LocalException
, and all user exceptions are derived from Ice::UserException
.
Ice run-time exceptions are all defined in Slice as local exceptions
. Local exception is a synonym for Ice run-time exception.
This figures shows the complete hierarchy of the Ice run-time exceptions:
Ice run-time exception hierarchy. (Shaded exceptions can be sent by the server.)
Note that Ice run-time exception hierarchy groups several exceptions into a single box to save space (which, strictly, is incorrect UML syntax). Also note that some run-time exceptions have data members, which, for brevity, we have omitted in the Ice run-time exception hierarchy. These data members provide additional information about the precise cause of an error.
Many of the run-time exceptions have self-explanatory names, such as MemoryLimitException
. Others indicate problems in the Ice run time, such as EncapsulationException
. Still others can arise only through application programming errors, such as TwowayOnlyException
. In practice, you will likely never see most of these exceptions. However, there are a few run-time exceptions you will encounter and whose meaning you should know.
Local Versus Remote Exceptions
Most error conditions are detected on the client side and raised locally in the client. For example, if an attempt to contact a server fails, the client-side run time raises a ConnectTimeoutException
.
However, there are a few specific error conditions (shown as shaded in the Ice run-time exception hierarchy diagram) that are detected by the server and transmitted to the client via the Ice protocol: ObjectNotExistException
, FacetNotExistException
and OperationNotExistException
(collectively the Request Failed exceptions) plus UnknownException
, UnknownLocalException
and UnknownUserException
(collectively the Unknown exceptions).
All other run-time exceptions (not shaded in the Ice run-time exception hierarchy) are detected by the client-side run time and are raised locally.
It is possible for the implementation of an operation to throw Ice run-time exceptions (as well as user exceptions). For example, if a client holds a proxy to an object that no longer exists in the server, your server application code is required to throw an ObjectNotExistException
. If you do throw run-time exceptions from your application code, you should take care to throw a run-time exception only if appropriate, that is, do not use run-time exceptions to indicate something that really should be a user exception. Doing so can be very confusing to the client: if the application "hijacks" some run-time exceptions for its own purposes, the client can no longer decide whether the exception was thrown by the Ice run time or by the server application code. This can make debugging very difficult.
Request Failed Exceptions
ObjectNotExistException
This exception indicates that a request was delivered to the server but the server could not locate a servant with the identity that is embedded in the proxy. In other words, the server could not find an object to dispatch the request to.
The Ice run time raises ObjectNotExistException
only if there are no facets in existence with a matching identity; otherwise, it raises FacetNotExistException
.
Most likely, this is the case because the object existed some time in the past and has since been destroyed, but the same exception is also raised if a client uses a proxy with the identity of an object that has never been created.
FacetNotExistException
The client attempted to contact a non-existent facet of an object, that is, the server has at least one servant with the given identity, but no servant with a matching facet name.
OperationNotExistException
This exception is raised if the server could locate an object with the correct identity but, on attempting to dispatch the client's operation invocation, the server found that the target object does not have such an operation. You will see this exception in only two cases:
- Client and server have been built with Slice definitions for an interface that disagree with each other, that is, the client was built with an interface definition for the object that indicates that an operation exists, but the server was built with a different version of the interface definition in which the operation is absent.
- You have used an unchecked down-cast on a proxy of the incorrect type.
ObjectNotExistException
, FacetNotExistException
and OperationNotExistException
derive from RequestFailedException
, and don't add any data member for this exception:
module Ice { local slice RequestFailException { Identity id; string facet; string operation; } }
RequestFailedException
itself is not transmissible as a response from a server to client—only the three derived exceptions are.
If you throw one of these three exceptions from the implementation of an operation, and you leave id
, facet
or operation
empty, Ice will automatically fill-in the missing data members using values from Current.
Unknown Exceptions
Any error condition on the server side that is not described by one of the three preceding exceptions is made known to the client as one of three generic exceptions: UnknownUserException
, UnknownLocalException
, or UnknownException
. Furthermore if a servant implementation throws one of these Unknown
exceptions, the Ice run time transmits it as is–it does not wrap it a new UnknownLocalException
.
module Ice { local exception UnknownException { string unknown; } local exception UnknownLocalException extends UnknownException { } local exception UnknownUserException extends UnknownException { } }
UnknownUserException
This exception indicates that an operation implementation has thrown a Slice exception that is not declared in the operation's exception specification (and is not derived from one of the exceptions in the operation's exception specification). Ice itself never throws this exception, as all user-exception checking for a given operation is performed only in the client's generated code and Ice run-time. It is nevertheless permissible for a servant to throw this exception.
UnknownLocalException
If an operation implementation raises a run-time exception other than ObjectNotExistException
, FacetNotExistException
, OperationNotExistException
or UnknownException
(such as a NotRegisteredException
), the client receives an UnknownLocalException
. In other words, the Ice protocol does not transmit the exact exception that was encountered in the server, but simply returns a bit to the client in the reply to indicate that the server encountered a run-time exception.
A common cause for a client receiving an UnknownLocalException
is failure to catch and handle all exceptions in the server. For example, if the implementation of an operation encounters an exception it does not handle, the exception propagates all the way up the call stack until the stack is unwound to the point where the Ice run time invoked the operation. The Ice run time catches all Ice exceptions that "escape" from an operation invocation and returns them to the client as an UnknownLocalException
.
UnknownException
An operation has thrown a non-Ice exception. For example, if the operation in the server throws a C++ exception, such as a std::bad_alloc, or a Java exception, such as a ClassCastException
, the client receives an UnknownException
.