CAPÍTULO I: ANTECEDENTES Y ESTADO DE LA CUESTIÓN
I.3. Antecedentes sobre escritura de los alumnos en matemáticas
I.3.5. Actividades de tipo “escritura expositiva” (expository writing)
CORBA makes remote communication as transparent as possible. At the source code level, sending a message to a CORBA object looks the same whether the object is implemented on a remote machine, is implemented in a different process on the same machine, or is actually linked into the client. However, by necessity, remote communication means that many more things can go wrong than for a local call. For example, connectivity may be lost because a bulldozer tears a cable.
IDL defines a number of system exceptions to capture common error conditions. Any operation can raise a system exception even if the operation has no raises expression. IDL defines 29 system exceptions. System exceptions have different names, but they all use the same exception body. The following definition uses the preprocessor to define a notational shorthand for the body of all the system exceptions (we will discuss the meaning of the data members in a moment):
enum completion_status {
COMPLETED_YES, COMPLETED_NO, COMPLETED_MAYBE };
#define SYSEX(NAME) exception NAME { \ unsigned long minor; \ completion_status completed; \ }
The system exceptions themselves are defined as follows.
SYSEX(BAD_CONTEXT); // error processing context object SYSEX(BAD_INV_ORDER); // routine invocations out of order SYSEX(BAD_OPERATION); // invalid operation
SYSEX(BAD_PARAM); // an invalid parameter was passed SYSEX(BAD_TYPECODE); // bad typecode
SYSEX(COMM_FAILURE); // communication failure SYSEX(DATA_CONVERSION); // data conversion error SYSEX(FREE_MEM); // cannot free memory
SYSEX(IMP_LIMIT); // violated implementation limit SYSEX(INITIALIZE); // ORB initialization failure SYSEX(INTERNAL); // ORB internal error
SYSEX(INTF_REPOS); // interface repository unavailable SYSEX(INVALID_TRANSACTION); // invalid TP context passed
SYSEX(INV_FLAG); // invalid flag was specified SYSEX(INV_IDENT); // invalid identifier syntax SYSEX(INV_OBJREF); // invalid object reference SYSEX(INV_POLICY); // invalid policy override
SYSEX(MARSHAL); // error marshaling param/result SYSEX(NO_IMPLEMENT); // implementation unavailable SYSEX(NO_MEMORY); // memory allocation failure SYSEX(NO_PERMISSION); // no permission for operation SYSEX(NO_RESOURCES); // out of resources for request SYSEX(NO_RESPONSE); // response not yet available SYSEX(OBJECT_NOT_EXIST); // no such object
SYSEX(PERSIST_STORE); // persistent storage failure SYSEX(TRANSACTION_REQUIRED); // operation needs transaction SYSEX(TRANSACTION_ROLLEDBACK); // operation was a no-op
SYSEX(TRANSIENT); // transient error, try again later SYSEX(UNKNOWN); // the unknown exception
Some of these exceptions, such as NO_MEMORY, have the obvious meaning. The meaning of others, such as BAD_INV_ORDER, is less obvious. Rather than list the meaning of every exception in detail here, we point out their uses as we discuss the relevant topic throughout the remainder of this book. The CORBA specification itself does not precisely state under exactly what circumstances each exception should be raised, so you have to expect different behavior from different ORBs (see Section 7.15.2).
An operation definition must not include system exceptions in its raises expression. It is understood that all operations may raise system exceptions. You are not allowed to explicitly state that, so the following is in error:
interface X {
void op1() raises(BAD_PARAM); // Illegal! void op2() raises(CORBA::BAD_PARAM); // Illegal! };
The list of system exceptions is open-ended and is occasionally added to by updates to the CORBA specification. To be future-proof, your code must be prepared to handle system exceptions not included in the preceding list in at least a general manner. If your code simply dumps core if it gets a new system exception, you will likely get problems as ORBs are upgraded over time (Section 7.15 shows how to deal with this problem). A system exception body contains two data members: minor and completed. The
completed member tells you at what point during call dispatch a failure occurred.
COMPLETED_YES
The failure occurred sometime after the operation in the server completed. This tells you that any state changes made by the failed invocation have happened.
Knowledge of whether the operation completed on the server side is important if an operation is not idempotent. An operation is idempotent if invoking it twice has the same effect as invoking it once. For example, the statement x=1; is idempotent, whereas the statement x++; is not.
COMPLETED_NO
The failure occurred on the way out of the client address space or on the way into the server address space. It is guaranteed that the target operation was not invoked, or, if it was invoked, no side effects of the operation have taken effect.
The completion status is indeterminate. This typically happens if the client invokes an operation and loses connectivity with the server while the call is still in progress. In this case, there is no way for the client run time to decide whether the operation was actually invoked in the server or whether the problem occurred before the request reached the servant.
The minor data member in system exceptions is meant to convey additional information about the exact cause of a failure with an error code. Unfortunately, CORBA does not specify the meaning of the minor codes and leaves their assignment to each ORB implementation (ORB vendors can reserve a section of minor code values for their exclusive use). For you as a developer, this means that there is no way to interpret the
minor member in your program, at least not if you want to write portable code.
However, the minor code can be useful for debugging if an ORB vendor uses it to provide further information about the precise cause of a system exception. This means that you should at least show the minor code when you report or log a system exception (even though you cannot interpret the minor code programmatically).