[thrift] C++: Pass std::exception from server to client
authordweatherford <dev-null@apache.org>
Sat, 15 Sep 2007 08:49:48 +0000 (08:49 +0000)
committerdweatherford <dev-null@apache.org>
Sat, 15 Sep 2007 08:49:48 +0000 (08:49 +0000)
Summary: Rather than an uncaught exception dropping the connection, catching std::exception (and anything derived from it) and passing its message payload back in the form of a T_EXCEPTION message is a much cleaner response.
Reviewed By: mcslee
Test Plan: compile generated code for Synapse's tablet interface, throw a generic exception at the server, observe the message for the exception arising from the client in the form of a TApplicationException (instead of the previous 'no more data to read' exception)
Revert: ok

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665264 13f79535-47bb-0310-9956-ffa450edef68

compiler/cpp/src/generate/t_cpp_generator.cc

index 7a31bc6..a92be52 100644 (file)
@@ -1799,11 +1799,9 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
   }
 
   // Try block for functions with exceptions
-  if (xceptions.size() > 0) {
-    f_service_ <<
-      indent() << "try {" << endl;
-    indent_up();
-  }
+  f_service_ <<
+    indent() << "try {" << endl;
+  indent_up();
 
   // Generate the function call
   t_struct* arg_struct = tfunction->get_arglist();
@@ -1839,9 +1837,10 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
       indent() << "result.__isset.success = true;" << endl;
   }
 
-  if (!tfunction->is_async() && xceptions.size() > 0) {
-    indent_down();
-    f_service_ << indent() << "}";
+  indent_down();
+  f_service_ << indent() << "}";
+
+  if (!tfunction->is_async()) {
     for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
       f_service_ << " catch (" << (*x_iter)->get_type()->get_name() << " &" << (*x_iter)->get_name() << ") {" << endl;
       if (!tfunction->is_async()) {
@@ -1855,9 +1854,24 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
         f_service_ << "}";
       }
     }
-    f_service_ << endl;
   }
 
+  f_service_ << " catch (const std::exception& e) {" << endl;
+
+  if (!tfunction->is_async()) {
+    indent_up();
+    f_service_ << 
+      indent() << "facebook::thrift::TApplicationException x(e.what());" << endl <<
+      indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() << "\", facebook::thrift::protocol::T_EXCEPTION, seqid);" << endl <<
+      indent() << "x.write(oprot);" << endl <<
+      indent() << "oprot->writeMessageEnd();" << endl <<
+      indent() << "oprot->getTransport()->flush();" << endl <<
+      indent() << "oprot->getTransport()->writeEnd();" << endl <<
+      indent() << "return;" << endl;
+    indent_down();
+  }
+  f_service_ << indent() << "}" << endl;
+
   // Shortcut out here for async functions
   if (tfunction->is_async()) {
     f_service_ <<