summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2007-11-05 23:43:07 +1000
committerMichi Henning <michi@zeroc.com>2007-11-05 23:43:07 +1000
commita2a5af41c5274fa7e254558841c1367d07a445d4 (patch)
treea7ede915600cc8dcb0df48c535bd602ec225e95c /cpp
parentFixed bug I introduced with the sequence mapping changes that caused (diff)
downloadice-a2a5af41c5274fa7e254558841c1367d07a445d4.tar.bz2
ice-a2a5af41c5274fa7e254558841c1367d07a445d4.tar.xz
ice-a2a5af41c5274fa7e254558841c1367d07a445d4.zip
Bug 2522 for C++ and Java.
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Ice/Outgoing.h2
-rw-r--r--cpp/slice/Ice/ServantLocator.ice22
-rw-r--r--cpp/src/Ice/Direct.cpp5
-rw-r--r--cpp/src/Ice/Outgoing.cpp38
-rw-r--r--cpp/src/Ice/Proxy.cpp76
-rw-r--r--cpp/src/Slice/JavaUtil.cpp11
-rwxr-xr-xcpp/src/slice2cpp/Gen.cpp63
-rw-r--r--cpp/src/slice2java/Gen.cpp138
-rw-r--r--cpp/test/Ice/exceptions/AllTests.cpp72
-rw-r--r--cpp/test/Ice/servantLocator/AllTests.cpp73
-rw-r--r--cpp/test/Ice/servantLocator/ServantLocatorI.cpp8
-rw-r--r--cpp/test/Ice/servantLocator/Test.ice5
-rw-r--r--cpp/test/Ice/servantLocator/TestAMD.ice5
-rw-r--r--cpp/test/Ice/servantLocator/TestAMDI.cpp39
-rw-r--r--cpp/test/Ice/servantLocator/TestAMDI.h4
-rw-r--r--cpp/test/Ice/servantLocator/TestI.cpp12
-rw-r--r--cpp/test/Ice/servantLocator/TestI.h5
17 files changed, 390 insertions, 188 deletions
diff --git a/cpp/include/Ice/Outgoing.h b/cpp/include/Ice/Outgoing.h
index 2ce534c3466..b190d64846f 100644
--- a/cpp/include/Ice/Outgoing.h
+++ b/cpp/include/Ice/Outgoing.h
@@ -49,6 +49,8 @@ public:
//
bool retry() const;
+ static void throwUnknownWrapper(const ::std::exception&);
+
private:
const LocalExceptionWrapper& operator=(const LocalExceptionWrapper&);
diff --git a/cpp/slice/Ice/ServantLocator.ice b/cpp/slice/Ice/ServantLocator.ice
index ce211927f9a..6654fd773a3 100644
--- a/cpp/slice/Ice/ServantLocator.ice
+++ b/cpp/slice/Ice/ServantLocator.ice
@@ -36,6 +36,15 @@ local interface ServantLocator
* the returned servant into its active servant map. This must be
* done by the servant locator implementation, if this is desired.
*
+ * [locate] can throw any user exception. If it does, that exception
+ * is marshaled back to the client. If the Slice definition for the
+ * corresponding operation includes that user exception, the client
+ * receives that user exception; otherwise, the client receives
+ * [UnknownUserException].
+ *
+ * If [locate] throws any exception, the Ice run time does <EM>not</EM>
+ * call [finished].
+ *
* <p class="Note">If you call [locate] from your own code, you
* must also call [finished] when you have finished using the
* servant, provided that [locate] returned a non-null servant;
@@ -55,7 +64,7 @@ local interface ServantLocator
* @see finished
*
**/
- Object locate(Current curr, out LocalObject cookie);
+ ["UserException"] Object locate(Current curr, out LocalObject cookie);
/**
*
@@ -64,6 +73,15 @@ local interface ServantLocator
* prior to the request and returned a non-null servant. This
* operation can be used for cleanup purposes after a request.
*
+ * [finished] can throw any user exception. If it does, that exception
+ * is marshaled back to the client. If the Slice definition for the
+ * corresponding operation includes that user exception, the client
+ * receives that user exception; otherwise, the client receives
+ * [UnknownUserException].
+ *
+ * If both the operation and [finished] throw an exception, the
+ * exception thrown by [finished] is marshaled back to the client.
+ *
* @param curr Information about the current operation call for
* which a servant was located by [locate].
*
@@ -76,7 +94,7 @@ local interface ServantLocator
* @see locate
*
**/
- void finished(Current curr, Object servant, LocalObject cookie);
+ ["UserException"] void finished(Current curr, Object servant, LocalObject cookie);
/**
*
diff --git a/cpp/src/Ice/Direct.cpp b/cpp/src/Ice/Direct.cpp
index a70078d1948..df8ff0ef107 100644
--- a/cpp/src/Ice/Direct.cpp
+++ b/cpp/src/Ice/Direct.cpp
@@ -145,6 +145,10 @@ IceInternal::Direct::destroy()
}
adapter->decDirectCount();
+ if(_userException.get())
+ {
+ _userException->ice_throw();
+ }
}
const ObjectPtr&
@@ -152,4 +156,3 @@ IceInternal::Direct::servant()
{
return _servant;
}
-
diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp
index d2c70989e72..53c333ba5f8 100644
--- a/cpp/src/Ice/Outgoing.cpp
+++ b/cpp/src/Ice/Outgoing.cpp
@@ -33,6 +33,44 @@ IceInternal::LocalExceptionWrapper::LocalExceptionWrapper(const LocalExceptionWr
_ex.reset(dynamic_cast<LocalException*>(ex.get()->ice_clone()));
}
+void
+IceInternal::LocalExceptionWrapper::throwUnknownWrapper(const std::exception& ex)
+{
+
+ const UserException* ue = dynamic_cast<const UserException*>(&ex);
+ if(ue)
+ {
+ stringstream s;
+ s << *ue;
+ throw LocalExceptionWrapper(UnknownUserException(__FILE__, __LINE__, s.str()), false);
+ }
+
+ const LocalException* le = dynamic_cast<const LocalException*>(&ex);
+ if(le)
+ {
+#if 0
+ //
+ // Commented-out code makes local exceptions fully location transparent,
+ // but the Freeze evictor relies on them not being transparent.
+ //
+ if(dynamic_cast<const UnknownException*>(le) ||
+ dynamic_cast<const ObjectNotExistException*>(le) ||
+ dynamic_cast<const OperationNotExistException*>(le) ||
+ dynamic_cast<const FacetNotExistException*>(le))
+ {
+ throw LocalExceptionWrapper(*le, false);
+ }
+ stringstream s;
+ s << *le;
+ throw LocalExceptionWrapper(UnknownLocalException(__FILE__, __LINE__, s.str()), false);
+#else
+ throw LocalExceptionWrapper(*le, false);
+#endif
+ }
+ string msg = "std::exception: ";
+ throw LocalExceptionWrapper(UnknownException(__FILE__, __LINE__, msg + ex.what()), false);
+}
+
const LocalException*
IceInternal::LocalExceptionWrapper::get() const
{
diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp
index b902dedaad1..35ee8cae257 100644
--- a/cpp/src/Ice/Proxy.cpp
+++ b/cpp/src/Ice/Proxy.cpp
@@ -1354,16 +1354,29 @@ IceDelegateD::Ice::Object::ice_isA(const string& __id, const Context* context)
{
__direct.servant()->__collocDispatch(__direct);
}
+ catch(const ::std::exception& __ex)
+ {
+ __direct.destroy();
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
catch(...)
{
__direct.destroy();
- throw;
+ throw UnknownException(__FILE__, __LINE__, "unknown c++ exception");
}
__direct.destroy();
}
- catch(const LocalException& __ex)
+ catch(const LocalExceptionWrapper&)
+ {
+ throw;
+ }
+ catch(const ::std::exception& __ex)
+ {
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
+ catch(...)
{
- throw LocalExceptionWrapper(__ex, false);
+ throw LocalExceptionWrapper(UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
}
return __result;
}
@@ -1399,16 +1412,29 @@ IceDelegateD::Ice::Object::ice_ping(const ::Ice::Context* context)
{
__direct.servant()->__collocDispatch(__direct);
}
+ catch(const ::std::exception& __ex)
+ {
+ __direct.destroy();
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
catch(...)
{
__direct.destroy();
- throw;
+ throw UnknownException(__FILE__, __LINE__, "unknown c++ exception");
}
__direct.destroy();
}
- catch(const LocalException& __ex)
+ catch(const LocalExceptionWrapper&)
+ {
+ throw;
+ }
+ catch(const ::std::exception& __ex)
+ {
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
+ catch(...)
{
- throw LocalExceptionWrapper(__ex, false);
+ throw LocalExceptionWrapper(UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
}
}
@@ -1449,16 +1475,29 @@ IceDelegateD::Ice::Object::ice_ids(const ::Ice::Context* context)
{
__direct.servant()->__collocDispatch(__direct);
}
+ catch(const ::std::exception& __ex)
+ {
+ __direct.destroy();
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
catch(...)
{
__direct.destroy();
- throw;
+ throw UnknownException(__FILE__, __LINE__, "unknown c++ exception");
}
__direct.destroy();
}
- catch(const LocalException& __ex)
+ catch(const LocalExceptionWrapper&)
+ {
+ throw;
+ }
+ catch(const ::std::exception& __ex)
+ {
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
+ catch(...)
{
- throw LocalExceptionWrapper(__ex, false);
+ throw LocalExceptionWrapper(UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
}
return __result;
}
@@ -1500,16 +1539,29 @@ IceDelegateD::Ice::Object::ice_id(const ::Ice::Context* context)
{
__direct.servant()->__collocDispatch(__direct);
}
+ catch(const ::std::exception& __ex)
+ {
+ __direct.destroy();
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
catch(...)
{
__direct.destroy();
- throw;
+ throw UnknownException(__FILE__, __LINE__, "unknown c++ exception");
}
__direct.destroy();
}
- catch(const LocalException& __ex)
+ catch(const LocalExceptionWrapper&)
+ {
+ throw;
+ }
+ catch(const ::std::exception& __ex)
+ {
+ LocalExceptionWrapper::throwUnknownWrapper(__ex);
+ }
+ catch(...)
{
- throw LocalExceptionWrapper(__ex, false);
+ throw LocalExceptionWrapper(UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
}
return __result;
}
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
index 8f27fb78708..a116b1a7a95 100644
--- a/cpp/src/Slice/JavaUtil.cpp
+++ b/cpp/src/Slice/JavaUtil.cpp
@@ -3442,6 +3442,17 @@ Slice::JavaGenerator::MetaDataVisitor::visitStructStart(const StructPtr& p)
void
Slice::JavaGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
+ if(p->hasMetaData("UserException"))
+ {
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
+ if(!cl->isLocal())
+ {
+ cout << p->definitionContext()->filename() << ":" << p->line()
+ << ": warning: metadata directive `UserException' applies only to local operations "
+ << "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name()
+ << "' is not local" << endl;
+ }
+ }
StringList metaData = getMetaData(p);
TypePtr returnType = p->returnType();
if(!metaData.empty())
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index ba7db40f1a4..2196a6953b5 100755
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -2926,7 +2926,11 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p)
if(!throws.empty())
{
C << eb;
-
+ C << nl << "catch(const ::Ice::UserException& __ex)";
+ C << sb;
+ C << nl << "setUserException(__ex);";
+ C << nl << "return ::Ice::DispatchUserException;";
+ C << eb;
throws.sort();
throws.unique();
#if defined(__SUNPRO_CC)
@@ -2935,14 +2939,6 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p)
throws.sort(Slice::DerivedToBaseCompare());
#endif
- for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i)
- {
- C << nl << "catch(const " << fixKwd((*i)->scoped()) << "& e)";
- C << sb;
- C << nl << "setUserException(e);";
- C << nl << "return ::Ice::DispatchUserException;";
- C << eb;
- }
}
C << eb;
@@ -2989,28 +2985,39 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p)
C << nl << "try";
C << sb;
- if(!throws.empty())
+ C << nl << "__direct.servant()->__collocDispatch(__direct);";
+ C << eb;
+ C << nl << "catch(const ::std::exception& __ex)";
+ C << sb;
+ C << nl << "__direct.destroy();";
+ C << nl << "::IceInternal::LocalExceptionWrapper::throwUnknownWrapper(__ex);";
+ C << eb;
+ C << nl << "catch(...)";
+ C << sb;
+ C << nl << "__direct.destroy();";
+ C << nl << "throw ::Ice::UnknownException(__FILE__, __LINE__, \"unknown c++ exception\");";
+ C << eb;
+ C << nl << "__direct.destroy();";
+ C << eb;
+ for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i)
{
- C << nl << "if(__direct.servant()->__collocDispatch(__direct) == ::Ice::DispatchUserException)";
+ C << nl << "catch(const " << fixKwd((*i)->scoped()) << "&)";
C << sb;
- C << nl << "__direct.throwUserException();";
+ C << nl << "throw;";
C << eb;
}
- else
- {
- C << nl << "__direct.servant()->__collocDispatch(__direct);";
- }
- C << eb;
- C << nl << "catch(...)";
+ C << nl << "catch(const ::IceInternal::LocalExceptionWrapper&)";
C << sb;
- C << nl << "__direct.destroy();";
C << nl << "throw;";
C << eb;
- C << nl << "__direct.destroy();";
+ C << nl << "catch(const ::std::exception& __ex)";
+ C << sb;
+ C << nl << "::IceInternal::LocalExceptionWrapper::throwUnknownWrapper(__ex);";
C << eb;
- C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << nl << "catch(...)";
C << sb;
- C << nl << "throw ::IceInternal::LocalExceptionWrapper(__ex, false);";
+ C << nl << "throw ::IceInternal::LocalExceptionWrapper("
+ << "::Ice::UnknownException(__FILE__, __LINE__, \"unknown c++ exception\"), false);";
C << eb;
if(ret)
{
@@ -5615,6 +5622,18 @@ Slice::Gen::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
ami = true;
}
+
+ if(p->hasMetaData("UserException"))
+ {
+ if(!cl->isLocal())
+ {
+ cout << p->definitionContext()->filename() << ":" << p->line()
+ << ": warning: metadata directive `UserException' applies only to local operations "
+ << "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name()
+ << "' is not local" << endl;
+ }
+ }
+
StringList metaData = p->getMetaData();
metaData.remove("cpp:const");
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index 471ecabc6ca..1b4f40edf09 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -540,7 +540,16 @@ Slice::JavaVisitor::writeDispatchAndMarshalling(Output& out, const ClassDefPtr&
{
out << sp << nl << "public final " << typeToString(ret, TypeModeReturn, package, op->getMetaData())
<< nl << opName << spar << params << epar;
- writeThrowsClause(package, throws);
+ if(op->hasMetaData("UserException"))
+ {
+ out.inc();
+ out << nl << "throws Ice.UserException";
+ out.dec();
+ }
+ else
+ {
+ writeThrowsClause(package, throws);
+ }
out << sb << nl;
if(ret)
{
@@ -1430,7 +1439,16 @@ Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent)
out << "Ice.Current __current";
}
out << epar;
- writeThrowsClause(package, throws);
+ if(op->hasMetaData("UserException"))
+ {
+ out.inc();
+ out << nl << "throws Ice.UserException";
+ out.dec();
+ }
+ else
+ {
+ writeThrowsClause(package, throws);
+ }
out << ';';
}
@@ -1595,10 +1613,19 @@ Slice::Gen::TieVisitor::visitClassDefStart(const ClassDefPtr& p)
}
out << epar;
- ExceptionList throws = (*r)->throws();
- throws.sort();
- throws.unique();
- writeThrowsClause(package, throws);
+ if((*r)->hasMetaData("UserException"))
+ {
+ out.inc();
+ out << nl << "throws Ice.UserException";
+ out.dec();
+ }
+ else
+ {
+ ExceptionList throws = (*r)->throws();
+ throws.sort();
+ throws.unique();
+ writeThrowsClause(package, throws);
+ }
out << sb;
out << nl;
if(ret && !hasAMD)
@@ -4325,7 +4352,10 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p)
out << nl << "final " << resultTypeHolder << " __result = new " << resultTypeHolder << "();";
}
- out << nl << "IceInternal.Direct __direct = new IceInternal.Direct(__current)";
+ out << nl << "IceInternal.Direct __direct = null;";
+ out << nl << "try";
+ out << sb;
+ out << nl << "__direct = new IceInternal.Direct(__current)";
out << sb;
out << nl << "public Ice.DispatchStatus run(Ice.Object __obj)";
out << sb;
@@ -4352,7 +4382,6 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p)
}
out << "__servant." << opName << spar << args << "__current" << epar << ';';
out << nl << "return Ice.DispatchStatus.DispatchOK;";
-
if(!throws.empty())
{
out << eb;
@@ -4362,50 +4391,80 @@ Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p)
out << nl << "return Ice.DispatchStatus.DispatchUserException;";
out << eb;
}
+
out << eb;
out << eb;
out << ";";
- out << nl << "try";
+ out << sp << nl << "Ice.DispatchStatus __status = __direct.servant().__collocDispatch(__direct);";
+ out << nl << "if(__status == Ice.DispatchStatus.DispatchUserException)";
out << sb;
- out << nl << "Ice.DispatchStatus __status = __direct.servant().__collocDispatch(__direct);";
- if(!throws.empty())
- {
- out << nl << "if(__status == Ice.DispatchStatus.DispatchUserException)";
- out << sb;
- out << nl << "try";
- out << sb;
- out << nl << "__direct.throwUserException();";
- out << eb;
- for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t)
- {
- string exS = getAbsolute(*t, package);
- out << nl << "catch(" << exS << " __ex)";
- out << sb;
- out << nl << "throw __ex;";
- out << eb;
- }
- out << nl << "catch(Ice.UserException __ex)";
- out << sb;
- out << nl << "assert false;";
- out << nl << "throw new Ice.UnknownUserException(__ex.toString());";
- out << eb;
- out << eb;
- }
+ out << nl << "__direct.throwUserException();";
+ out << eb;
out << nl << "assert __status == Ice.DispatchStatus.DispatchOK;";
if(ret)
{
out << nl << "return __result.value;";
}
+
out << eb;
+ for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t)
+ {
+ string exS = getAbsolute(*t, package);
+ out << nl << "catch(" << exS << " __ex)";
+ out << sb;
+ out << nl << "throw __ex;";
+ out << eb;
+ }
+
+ //
+ // Next two catch handlers keep local exceptions non-transparent.
+ //
+ out << nl << "catch(Ice.UserException __ex)";
+ out << sb;
+ out << nl << "IceInternal.LocalExceptionWrapper.throwUnknownWrapper(__ex);";
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "IceInternal.LocalExceptionWrapper.throwUnknownWrapper(__ex);";
+ out << eb;
+
+ /*
+ //
+ // Commented-out code makes local exceptions fully location transparent,
+ // but the Freeze evictor relies on them being non-transparent.
+ //
out << nl << "catch(Ice.LocalException __ex)";
out << sb;
- out << nl << "throw new IceInternal.LocalExceptionWrapper(__ex, false);";
+ out << nl << "IceInternal.LocalExceptionWrapper.throwUnknownWrapper(__ex);";
out << eb;
+ */
out << nl << "finally";
out << sb;
+ out << nl << "if(__direct != null)";
+ out << sb;
+ out << nl << "try";
+ out << sb;
out << nl << "__direct.destroy();";
out << eb;
+ for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t)
+ {
+ string exS = getAbsolute(*t, package);
+ out << nl << "catch(" << exS << " __ex)";
+ out << sb;
+ out << nl << "throw __ex;";
+ out << eb;
+ }
+ out << nl << "catch(java.lang.Throwable __ex)";
+ out << sb;
+ out << nl << "IceInternal.LocalExceptionWrapper.throwUnknownWrapper(__ex);";
+ out << eb;
+ out << eb;
+ out << eb;
+ }
+ if(ret && !cl->hasMetaData("amd") && !op->hasMetaData("amd"))
+ {
+ out << nl << "return __result.value;";
}
out << eb;
}
@@ -4688,7 +4747,16 @@ Slice::Gen::BaseImplVisitor::writeOperation(Output& out, const string& package,
throws.sort();
throws.unique();
- writeThrowsClause(package, throws);
+ if(op->hasMetaData("UserException"))
+ {
+ out.inc();
+ out << nl << "throws Ice.UserException";
+ out.dec();
+ }
+ else
+ {
+ writeThrowsClause(package, throws);
+ }
out << sb;
diff --git a/cpp/test/Ice/exceptions/AllTests.cpp b/cpp/test/Ice/exceptions/AllTests.cpp
index 84efae4b113..457169e9609 100644
--- a/cpp/test/Ice/exceptions/AllTests.cpp
+++ b/cpp/test/Ice/exceptions/AllTests.cpp
@@ -961,22 +961,8 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
thrower->throwUndeclaredA(1);
test(false);
}
- catch(const A& ex)
- {
- //
- // We get the original exception with collocation
- // optimization.
- //
- test(collocated);
- test(ex.aMem == 1);
- }
catch(const Ice::UnknownUserException&)
{
- //
- // We get an unknown user exception without collocation
- // optimization.
- //
- test(!collocated);
}
catch(...)
{
@@ -988,23 +974,8 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
thrower->throwUndeclaredB(1, 2);
test(false);
}
- catch(const B& ex)
- {
- //
- // We get the original exception with collocation
- // optimization.
- //
- test(collocated);
- test(ex.aMem == 1);
- test(ex.bMem == 2);
- }
catch(const Ice::UnknownUserException&)
{
- //
- // We get an unknown user exception without collocation
- // optimization.
- //
- test(!collocated);
}
catch(...)
{
@@ -1016,24 +987,8 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
thrower->throwUndeclaredC(1, 2, 3);
test(false);
}
- catch(const C& ex)
- {
- //
- // We get the original exception with collocation
- // optimization.
- //
- test(collocated);
- test(ex.aMem == 1);
- test(ex.bMem == 2);
- test(ex.cMem == 3);
- }
catch(const Ice::UnknownUserException&)
{
- //
- // We get an unknown user exception without
- // collocation optimization.
- //
- test(!collocated);
}
catch(...)
{
@@ -1112,22 +1067,14 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
thrower->throwLocalException();
test(false);
}
- catch(const Ice::TimeoutException&)
- {
- //
- // We get the original exception with collocation
- // optimization.
- //
- test(collocated);
- }
catch(const Ice::UnknownLocalException&)
{
- //
- // We get an unknown local exception without collocation
- // optimization.
- //
test(!collocated);
}
+ catch(const Ice::TimeoutException&)
+ {
+ test(collocated);
+ }
catch(...)
{
test(false);
@@ -1144,19 +1091,10 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
}
catch(const Ice::UnknownException&)
{
- //
- // We get an unknown exception without collocation
- // optimization.
- //
- assert(!collocated);
}
catch(...)
{
- //
- // We get the original exception with collocation
- // optimization.
- //
- assert(collocated);
+ test(false);
}
cout << "ok" << endl;
diff --git a/cpp/test/Ice/servantLocator/AllTests.cpp b/cpp/test/Ice/servantLocator/AllTests.cpp
index c9de4b3aa52..935dafb32e6 100644
--- a/cpp/test/Ice/servantLocator/AllTests.cpp
+++ b/cpp/test/Ice/servantLocator/AllTests.cpp
@@ -33,6 +33,10 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
test(ex.operation == "requestFailedException");
}
}
+ catch(...)
+ {
+ test(false);
+ }
try
{
@@ -43,6 +47,10 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
{
test(ex.unknown == "reason");
}
+ catch(...)
+ {
+ test(false);
+ }
try
{
@@ -71,13 +79,11 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
}
catch(const UnknownUserException& ex)
{
- //cerr << ex.unknown << endl;
- test(!collocated);
test(ex.unknown == "Test::TestIntfUserException");
}
- catch(const TestIntfUserException&)
+ catch(...)
{
- test(collocated);
+ test(false);
}
try
@@ -87,7 +93,6 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
}
catch(const UnknownLocalException& ex)
{
- //cerr << ex.unknown << endl;
test(!collocated);
test(ex.unknown.find("Ice::SocketException:\nsocket exception: unknown error") != string::npos);
}
@@ -95,6 +100,10 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
{
test(collocated);
}
+ catch(...)
+ {
+ test(false);
+ }
try
{
@@ -103,13 +112,11 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
}
catch(const UnknownException& ex)
{
- //cerr << ex.unknown << endl;
- test(!collocated);
test(ex.unknown == "std::exception: Hello");
}
- catch(const std::runtime_error&)
+ catch(...)
{
- test(collocated);
+ test(false);
}
try
@@ -119,13 +126,11 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
}
catch(const UnknownException& ex)
{
- //cerr << ex.unknown << endl;
- test(!collocated);
test(ex.unknown == "unknown c++ exception");
}
- catch(const int&)
+ catch(...)
{
- test(collocated);
+ test(false);
}
try
@@ -137,14 +142,19 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
{
test(ex.unknown == "reason");
}
+ catch(...)
+ {
+ test(false);
+ }
try
{
- obj->intfUserException();
+ obj->impossibleException(false);
test(false);
}
- catch(const TestIntfUserException&)
+ catch(const UnknownUserException&)
{
+ // Operation doesn't throw, but locate() and finshed() throw TestIntfUserException.
}
catch(...)
{
@@ -153,22 +163,45 @@ testExceptions(const TestIntfPrx& obj, bool collocated)
try
{
- obj->impossibleException();
+ obj->impossibleException(true);
test(false);
}
- catch(const TestImpossibleException&)
+ catch(const UnknownUserException&)
{
- test(collocated);
+ // Operation doesn't throw, but locate() and finshed() throw TestIntfUserException.
}
- catch(const UnknownUserException&)
+ catch(...)
{
- test(!collocated);
+ test(false);
+ }
+
+ try
+ {
+ obj->intfUserException(false);
+ test(false);
+ }
+ catch(const TestImpossibleException&)
+ {
+ // Operation doesn't throw, but locate() and finished() throw TestImpossibleException.
}
catch(...)
{
test(false);
}
+ try
+ {
+ obj->intfUserException(true);
+ test(false);
+ }
+ catch(const TestImpossibleException&)
+ {
+ // Operation throws TestIntfUserException, but locate() and finished() throw TestImpossibleException.
+ }
+ catch(...)
+ {
+ test(false);
+ }
}
TestIntfPrx
diff --git a/cpp/test/Ice/servantLocator/ServantLocatorI.cpp b/cpp/test/Ice/servantLocator/ServantLocatorI.cpp
index c7203f2502d..37e92f50f0d 100644
--- a/cpp/test/Ice/servantLocator/ServantLocatorI.cpp
+++ b/cpp/test/Ice/servantLocator/ServantLocatorI.cpp
@@ -111,12 +111,12 @@ ServantLocatorI::exception(const Ice::Current& current)
{
throw UnknownException(__FILE__, __LINE__, "reason");
}
- else if(current.operation == "intfUserException")
+ else if(current.operation == "impossibleException")
{
- throw TestIntfUserException();
+ throw TestIntfUserException(); // Yes, it really is meant to be TestIntfUserException.
}
- else if(current.operation == "impossibleException")
+ else if(current.operation == "intfUserException")
{
- throw TestImpossibleException();
+ throw TestImpossibleException(); // Yes, it really is meant to be TestImpossibleException.
}
}
diff --git a/cpp/test/Ice/servantLocator/Test.ice b/cpp/test/Ice/servantLocator/Test.ice
index 3790b54b479..6ed5c333213 100644
--- a/cpp/test/Ice/servantLocator/Test.ice
+++ b/cpp/test/Ice/servantLocator/Test.ice
@@ -34,9 +34,8 @@ interface TestIntf
void unknownExceptionWithServantException();
- string intfUserException() throws TestIntfUserException;
-
- string impossibleException() throws TestIntfUserException;
+ string impossibleException(bool throw) throws TestImpossibleException;
+ string intfUserException(bool throw) throws TestIntfUserException, TestImpossibleException;
void shutdown();
};
diff --git a/cpp/test/Ice/servantLocator/TestAMD.ice b/cpp/test/Ice/servantLocator/TestAMD.ice
index a8ec1209e50..e1cc20de804 100644
--- a/cpp/test/Ice/servantLocator/TestAMD.ice
+++ b/cpp/test/Ice/servantLocator/TestAMD.ice
@@ -34,9 +34,8 @@ exception TestImpossibleException
void unknownExceptionWithServantException();
- string intfUserException() throws TestIntfUserException;
-
- string impossibleException() throws TestIntfUserException;
+ string impossibleException(bool throw) throws TestImpossibleException;
+ string intfUserException(bool throw) throws TestIntfUserException, TestImpossibleException;
void shutdown();
};
diff --git a/cpp/test/Ice/servantLocator/TestAMDI.cpp b/cpp/test/Ice/servantLocator/TestAMDI.cpp
index 970ef71134e..e6d7dbf9e3e 100644
--- a/cpp/test/Ice/servantLocator/TestAMDI.cpp
+++ b/cpp/test/Ice/servantLocator/TestAMDI.cpp
@@ -69,23 +69,38 @@ TestAMDI::unknownExceptionWithServantException_async(const Test::AMD_TestIntf_un
}
void
-TestAMDI::intfUserException_async(const Test::AMD_TestIntf_intfUserExceptionPtr& cb, const Current&)
+TestAMDI::impossibleException_async(const Test::AMD_TestIntf_impossibleExceptionPtr& cb, bool _cpp_throw,
+ const Current&)
{
- //
- // Return a value so we can be sure that the stream position
- // is reset correctly if finished() throws.
- //
- cb->ice_response("Hello");
+ if(_cpp_throw)
+ {
+ cb->ice_exception(Test::TestImpossibleException());
+ }
+ else
+ {
+ //
+ // Return a value so we can be sure that the stream position
+ // is reset correctly if finished() throws.
+ //
+ cb->ice_response("Hello");
+ }
}
void
-TestAMDI::impossibleException_async(const Test::AMD_TestIntf_impossibleExceptionPtr& cb, const Current&)
+TestAMDI::intfUserException_async(const Test::AMD_TestIntf_intfUserExceptionPtr& cb, bool _cpp_throw, const Current&)
{
- //
- // Return a value so we can be sure that the stream position
- // is reset correctly if finished() throws.
- //
- cb->ice_response("Hello");
+ if(_cpp_throw)
+ {
+ cb->ice_exception(Test::TestIntfUserException());
+ }
+ else
+ {
+ //
+ // Return a value so we can be sure that the stream position
+ // is reset correctly if finished() throws.
+ //
+ cb->ice_response("Hello");
+ }
}
void
diff --git a/cpp/test/Ice/servantLocator/TestAMDI.h b/cpp/test/Ice/servantLocator/TestAMDI.h
index aed39a6bca0..909b9bc6df5 100644
--- a/cpp/test/Ice/servantLocator/TestAMDI.h
+++ b/cpp/test/Ice/servantLocator/TestAMDI.h
@@ -28,8 +28,8 @@ public:
virtual void unknownExceptionWithServantException_async(
const Test::AMD_TestIntf_unknownExceptionWithServantExceptionPtr&, const Ice::Current&);
- virtual void intfUserException_async(const Test::AMD_TestIntf_intfUserExceptionPtr&, const Ice::Current&);
- virtual void impossibleException_async(const Test::AMD_TestIntf_impossibleExceptionPtr&, const Ice::Current&);
+ virtual void impossibleException_async(const Test::AMD_TestIntf_impossibleExceptionPtr&, bool, const Ice::Current&);
+ virtual void intfUserException_async(const Test::AMD_TestIntf_intfUserExceptionPtr&, bool, const Ice::Current&);
virtual void shutdown_async(const Test::AMD_TestIntf_shutdownPtr&, const Ice::Current&);
};
diff --git a/cpp/test/Ice/servantLocator/TestI.cpp b/cpp/test/Ice/servantLocator/TestI.cpp
index cbb310c7ffc..0de709f3a36 100644
--- a/cpp/test/Ice/servantLocator/TestI.cpp
+++ b/cpp/test/Ice/servantLocator/TestI.cpp
@@ -61,8 +61,12 @@ TestI::unknownExceptionWithServantException(const Current&)
}
string
-TestI::intfUserException(const Current&)
+TestI::impossibleException(bool _cpp_throw, const Current&)
{
+ if(_cpp_throw)
+ {
+ throw Test::TestImpossibleException();
+ }
//
// Return a value so we can be sure that the stream position
// is reset correctly if finished() throws.
@@ -71,8 +75,12 @@ TestI::intfUserException(const Current&)
}
string
-TestI::impossibleException(const Current&)
+TestI::intfUserException(bool _cpp_throw, const Current&)
{
+ if(_cpp_throw)
+ {
+ throw Test::TestIntfUserException();
+ }
//
// Return a value so we can be sure that the stream position
// is reset correctly if finished() throws.
diff --git a/cpp/test/Ice/servantLocator/TestI.h b/cpp/test/Ice/servantLocator/TestI.h
index c3df4f43389..53f93ff474b 100644
--- a/cpp/test/Ice/servantLocator/TestI.h
+++ b/cpp/test/Ice/servantLocator/TestI.h
@@ -27,9 +27,8 @@ public:
virtual void unknownExceptionWithServantException(const Ice::Current&);
- virtual ::std::string intfUserException(const Ice::Current&);
-
- virtual ::std::string impossibleException(const Ice::Current&);
+ virtual ::std::string impossibleException(bool, const Ice::Current&);
+ virtual ::std::string intfUserException(bool, const Ice::Current&);
virtual void shutdown(const Ice::Current&);
};