diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/slice/Ice/LocalException.ice | 45 | ||||
-rw-r--r-- | cpp/src/Ice/Exception.cpp | 50 | ||||
-rw-r--r-- | cpp/src/Ice/Incoming.cpp | 77 | ||||
-rw-r--r-- | cpp/src/Ice/Outgoing.cpp | 59 |
4 files changed, 123 insertions, 108 deletions
diff --git a/cpp/slice/Ice/LocalException.ice b/cpp/slice/Ice/LocalException.ice index b241dd3a986..f51865992ee 100644 --- a/cpp/slice/Ice/LocalException.ice +++ b/cpp/slice/Ice/LocalException.ice @@ -20,10 +20,12 @@ module Ice /** * * This exception is raised if an operation call on a server raises a - * local exception. Since the exception is local, it is not - * transmitted by the &Ice; protocol. Instead, the client only receives - * an [UknownLocalException] for all local exceptions being raised by - * the server. + * local exception. Because local exceptions are not transmitted by + * the &Ice; protocol, the client receives all local exceptions raised + * by the server as [UknownLocalException]. The only exception to this + * rule are all exceptions derived from [RequestFailedException], + * which are transmitted by the &Ice; protocol even though they are + * declared [local]. * **/ local exception UnknownLocalException @@ -170,16 +172,31 @@ local exception LocationForwardIdentityException /** * - * This exception is raised if an object does not exist on the server. - * - * @see ObjectAdapter::add - * @see ObjectAdapter::addServantLocator + * This exception is raised if a request failed. This exception, and + * all exceptions derived from [RequestFailedException], is + * transmitted by the &Ice; protocol, even though it is declared + * [local]. * **/ -local exception ObjectNotExistException +local exception RequestFailedException { - /** The identity of the object that does exist. */ + /** The identity of the Ice Object to which the request was sent to. */ Identity id; + + /** The facet to which the request was sent to. */ + FacetPath facet; + + /** The operation name of the request. */ + string operation; +}; + +/** + * + * This exception is raised if an object does not exist on the server. + * + **/ +local exception ObjectNotExistException extends RequestFailedException +{ }; /** @@ -188,10 +205,8 @@ local exception ObjectNotExistException * facet path. * **/ -local exception FacetNotExistException +local exception FacetNotExistException extends RequestFailedException { - /** The facet that does exist. */ - FacetPath facet; }; /** @@ -201,10 +216,8 @@ local exception FacetNotExistException * client or the server using an outdated Slice specification. * **/ -local exception OperationNotExistException +local exception OperationNotExistException extends RequestFailedException { - /** The operation name that does exist. */ - string operation; }; /** diff --git a/cpp/src/Ice/Exception.cpp b/cpp/src/Ice/Exception.cpp index 7d818ddee6f..fe16488409e 100644 --- a/cpp/src/Ice/Exception.cpp +++ b/cpp/src/Ice/Exception.cpp @@ -116,38 +116,56 @@ Ice::LocationForwardIdentityException::ice_print(ostream& out) const out << ":\nidentity mismatch in location forward"; } -void -Ice::ObjectNotExistException::ice_print(ostream& out) const +static void +printFailedRequestData(ostream& out, const RequestFailedException& ex) { - Exception::ice_print(out); - out << ":\nobject `" << identityToString(id) << "' does not exist"; -} - -void -Ice::FacetNotExistException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ":\nfacet `"; - vector<string>::const_iterator p = facet.begin(); - while(p != facet.end()) + out << "\nidentity: " << identityToString(ex.id); + out << "\nfacet: "; + vector<string>::const_iterator p = ex.facet.begin(); + while(p != ex.facet.end()) { // // TODO: Escape for whitespace and slashes. // out << *p++; - if(p != facet.end()) + if(p != ex.facet.end()) { out << '/'; } } - out << "' does not exist"; + out << "\noperation: " << ex.operation; +} + +void +Ice::RequestFailedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nrequest failed"; + printFailedRequestData(out, *this); +} + +void +Ice::ObjectNotExistException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nobject does not exist"; + printFailedRequestData(out, *this); +} + +void +Ice::FacetNotExistException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nfacet does not exist"; + printFailedRequestData(out, *this); } void Ice::OperationNotExistException::ice_print(ostream& out) const { Exception::ice_print(out); - out << ":\noperation `" << operation << "' does not exist"; + out << ":\noperation does not exist"; + printFailedRequestData(out, *this); } void diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp index 995f90d4085..8e6458aae69 100644 --- a/cpp/src/Ice/Incoming.cpp +++ b/cpp/src/Ice/Incoming.cpp @@ -132,21 +132,16 @@ IceInternal::Incoming::invoke(bool response) if(status != DispatchOK && status != DispatchUserException) { + assert(status == DispatchObjectNotExist || + status == DispatchFacetNotExist || + status == DispatchOperationNotExist); + _os.b.resize(statusPos); _os.write(static_cast<Byte>(status)); - if(status == DispatchObjectNotExist) - { - current.id.__write(&_os); - } - else if(status == DispatchFacetNotExist) - { - _os.write(current.facet); - } - else if(status == DispatchOperationNotExist) - { - _os.write(current.operation); - } + current.id.__write(&_os); + _os.write(current.facet); + _os.write(current.operation); } else { @@ -171,7 +166,7 @@ IceInternal::Incoming::invoke(bool response) _os.write(ex._prx); } } - catch(const ObjectNotExistException& ex) + catch(const RequestFailedException& ex) { if(locator && servant) { @@ -184,51 +179,29 @@ IceInternal::Incoming::invoke(bool response) { _os.endWriteEncaps(); _os.b.resize(statusPos); - _os.write(static_cast<Byte>(DispatchObjectNotExist)); + if(dynamic_cast<const ObjectNotExistException*>(&ex)) + { + _os.write(static_cast<Byte>(DispatchObjectNotExist)); + } + else if(dynamic_cast<const FacetNotExistException*>(&ex)) + { + _os.write(static_cast<Byte>(DispatchFacetNotExist)); + } + else if(dynamic_cast<const OperationNotExistException*>(&ex)) + { + _os.write(static_cast<Byte>(DispatchOperationNotExist)); + } + else + { + assert(false); + } + // Not current.id.__write(_os), so that the identity // can be overwritten. ex.id.__write(&_os); - } - - // Rethrow, so that the caller can print a warning. - ex.ice_throw(); - } - catch(const FacetNotExistException& ex) - { - if(locator && servant) - { - assert(_adapter); - locator->finished(current, servant, cookie); - } - - _is.endReadEncaps(); - if(response) - { - _os.endWriteEncaps(); - _os.b.resize(statusPos); - _os.write(static_cast<Byte>(DispatchFacetNotExist)); // Not _os.write(current.facet), so that the facet can // be overwritten. _os.write(ex.facet); - } - - // Rethrow, so that the caller can print a warning. - ex.ice_throw(); - } - catch(const OperationNotExistException& ex) - { - if(locator && servant) - { - assert(_adapter); - locator->finished(current, servant, cookie); - } - - _is.endReadEncaps(); - if(response) - { - _os.endWriteEncaps(); - _os.b.resize(statusPos); - _os.write(static_cast<Byte>(DispatchOperationNotExist)); // Not _os.write(current.operation), so that the operation // can be overwritten. _os.write(ex.operation); diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp index e5f2dd52318..dd207ca36f7 100644 --- a/cpp/src/Ice/Outgoing.cpp +++ b/cpp/src/Ice/Outgoing.cpp @@ -247,41 +247,52 @@ IceInternal::Outgoing::finished(BasicStream& is) } case DispatchObjectNotExist: - { - _state = StateLocalException; - // Don't do ex->identity.read(_is), as this operation - // might throw exceptions. In such case ex would leak. - Identity ident; - ident.__read(&_is); - ObjectNotExistException* ex = new ObjectNotExistException(__FILE__, __LINE__); - ex->id = ident; - _exception = auto_ptr<LocalException>(ex); - break; - } - case DispatchFacetNotExist: + case DispatchOperationNotExist: { _state = StateLocalException; // Don't do _is.read(ex->facet), as this operation // might throw exceptions. In such case ex would leak. + Identity ident; + ident.__read(&_is); vector<string> facet; _is.read(facet); - FacetNotExistException* ex = new FacetNotExistException(__FILE__, __LINE__); - ex->facet = facet; - _exception = auto_ptr<LocalException>(ex); - break; - } - - case DispatchOperationNotExist: - { - _state = StateLocalException; - // Don't do _is.read(ex->operation), as this operation - // might throw exceptions. In such case ex would leak. string operation; _is.read(operation); - OperationNotExistException* ex = new OperationNotExistException(__FILE__, __LINE__); + + RequestFailedException* ex; + switch(static_cast<DispatchStatus>(status)) + { + case DispatchObjectNotExist: + { + ex = new ObjectNotExistException(__FILE__, __LINE__); + break; + } + + case DispatchFacetNotExist: + { + ex = new FacetNotExistException(__FILE__, __LINE__); + break; + } + + case DispatchOperationNotExist: + { + ex = new OperationNotExistException(__FILE__, __LINE__); + break; + } + + default: + { + assert(false); + break; + } + } + + ex->id = ident; + ex->facet = facet; ex->operation = operation; _exception = auto_ptr<LocalException>(ex); + break; } |