THRIFT-1269 thrift: handle undeclared exceptions in the async

git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1160453 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index 0900ba7..d9c2548 100755
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -3204,10 +3204,19 @@
           indent() << "  return throw_" << tfunction->get_name() <<
           "(cob, seqid, _oprot, ctx, _throw);" << endl <<
           indent() << "}" << endl <<
-          indent() << "  T_GENERIC_PROTOCOL(this, oprot, _oprot);" <<
+          indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" <<
           endl << endl;
       }
 
+      // Get the event handler context
+      out <<
+        endl <<
+        indent() << "if (eventHandler_.get() != NULL) {" << endl <<
+        indent() << "  ctx = eventHandler_->getContext(\"" << service_func_name << "\", NULL);" << endl <<
+        indent() << "}" << endl <<
+        indent() << "apache::thrift::TProcessorContextFreer freer(eventHandler_.get(), ctx, \"" << service_func_name << "\");" << endl << endl;
+
+      // Throw the TDelayedException, and catch the result
       out <<
         indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;" << endl << endl <<
         indent() << "try {" << endl;
@@ -3226,15 +3235,32 @@
           indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << endl;
         scope_down(out);
       }
-      // TODO(dreiss): Handle the case where an undeclared exception is thrown?
+
+      // Handle the case where an undeclared exception is thrown
+      out << " catch (std::exception& e) {" << endl;
+      indent_up();
+      out <<
+        indent() << "if (eventHandler_.get() != NULL) {" << endl <<
+        indent() << "  eventHandler_->handlerError(ctx, \"" <<
+          service_func_name << "\");" << endl <<
+        indent() << "}" << endl <<
+        endl <<
+        indent() << "apache::thrift::TApplicationException x(e.what());" <<
+          endl <<
+        indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() <<
+          "\", apache::thrift::protocol::T_EXCEPTION, seqid);" << endl <<
+        indent() << "x.write(oprot);" << endl <<
+        indent() << "oprot->writeMessageEnd();" << endl <<
+        indent() << "oprot->getTransport()->writeEnd();" << endl <<
+        indent() << "oprot->getTransport()->flush();" << endl <<
+        // We pass true to the cob here, since we did successfully write a
+        // response, even though it is an exception response.
+        // It looks like the argument is currently ignored, anyway.
+        indent() << "return cob(true);" << endl;
+      scope_down(out);
 
       // Serialize the result into a struct
       out <<
-        endl <<
-        indent() << "if (eventHandler_.get() != NULL) {" << endl <<
-        indent() << "  ctx = eventHandler_->getContext(\"" << service_func_name << "\", NULL);" << endl <<
-        indent() << "}" << endl <<
-        indent() << "::apache::thrift::TProcessorContextFreer freer(eventHandler_.get(), ctx, \"" << service_func_name << "\");" << endl << endl <<
         indent() << "if (eventHandler_.get() != NULL) {" << endl <<
         indent() << "  eventHandler_->preWrite(ctx, \"" << service_func_name << "\");" << endl <<
         indent() << "}" << endl << endl <<