You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2015/09/23 21:23:42 UTC

[2/2] thrift git commit: THRIFT-3349 Python server does not handle processor exception Client: Python Patch: Nobuaki Sukegawa

THRIFT-3349 Python server does not handle processor exception
Client: Python
Patch: Nobuaki Sukegawa <ns...@gmail.com>

This closes #621


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/8c7b03c2
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/8c7b03c2
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/8c7b03c2

Branch: refs/heads/master
Commit: 8c7b03c2a56d157d95cf98df3539128fd353ebe5
Parents: d629ea0
Author: Jens Geyer <je...@apache.org>
Authored: Wed Sep 23 21:18:13 2015 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Wed Sep 23 21:20:57 2015 +0200

----------------------------------------------------------------------
 compiler/cpp/src/generate/t_py_generator.cc | 66 +++++++++++++-----------
 1 file changed, 37 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/8c7b03c2/compiler/cpp/src/generate/t_py_generator.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc
index 10b1680..9c43b1f 100644
--- a/compiler/cpp/src/generate/t_py_generator.cc
+++ b/compiler/cpp/src/generate/t_py_generator.cc
@@ -66,7 +66,7 @@ public:
       gen_newstyle_ = 0; // dynamic is newstyle
       gen_dynbaseclass_ = "TBase";
       gen_dynbaseclass_exc_ = "TExceptionBase";
-      import_dynbase_ = "from thrift.protocol.TBase import TBase, TExceptionBase\n";
+      import_dynbase_ = "from thrift.protocol.TBase import TBase, TExceptionBase, TTransport\n";
     }
 
     iter = parsed_options.find("dynbase");
@@ -960,7 +960,9 @@ void t_py_generator::generate_service(t_service* tservice) {
                << tservice->get_extends()->get_name() << endl;
   }
 
-  f_service_ << "from ttypes import *" << endl << "from thrift.Thrift import TProcessor" << endl
+  f_service_ << "import logging" << endl
+             << "from ttypes import *" << endl
+             << "from thrift.Thrift import TProcessor" << endl
              << render_fastbinary_includes() << endl;
 
   if (gen_twisted_) {
@@ -1656,6 +1658,8 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function*
   }
 
   if (gen_twisted_) {
+    // TODO: Propagate arbitrary exception raised by handler to client as does plain "py"
+
     // Generate the function call
     t_struct* arg_struct = tfunction->get_arglist();
     const std::vector<t_field*>& fields = arg_struct->get_members();
@@ -1760,6 +1764,8 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function*
     }
     */
 
+    // TODO: Propagate arbitrary exception raised by handler to client as does plain "py"
+
     // Generate the function call
     t_struct* arg_struct = tfunction->get_arglist();
     const std::vector<t_field*>& fields = arg_struct->get_members();
@@ -1814,10 +1820,9 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function*
 
   } else { // py
     // Try block for a function with exceptions
-    if (xceptions.size() > 0) {
-      f_service_ << indent() << "try:" << endl;
-      indent_up();
-    }
+    // It also catches arbitrary exceptions raised by handler method to propagate them to the client
+    f_service_ << indent() << "try:" << endl;
+    indent_up();
 
     // Generate the function call
     t_struct* arg_struct = tfunction->get_arglist();
@@ -1838,37 +1843,40 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function*
       }
       f_service_ << "args." << (*f_iter)->get_name();
     }
-    f_service_ << ")" << endl;
+    f_service_ << ")" << endl << indent() << "msg_type = TMessageType.REPLY" << endl;
 
-    if (!tfunction->is_oneway() && xceptions.size() > 0) {
-      indent_down();
+    indent_down();
+    f_service_ << indent()
+               << "except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):" << endl
+               << indent() << "  raise" << endl;
+
+    if (!tfunction->is_oneway()) {
       for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
         f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as "
                    << (*x_iter)->get_name() << ":" << endl;
-        if (!tfunction->is_oneway()) {
-          indent_up();
-          f_service_ << indent() << "result." << (*x_iter)->get_name() << " = "
-                     << (*x_iter)->get_name() << endl;
-          indent_down();
-        } else {
-          f_service_ << indent() << "pass" << endl;
-        }
+        indent_up();
+        f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl
+                   << indent() << "result." << (*x_iter)->get_name() << " = "
+                   << (*x_iter)->get_name() << endl;
+        indent_down();
       }
-    }
 
-    // Shortcut out here for oneway functions
-    if (tfunction->is_oneway()) {
-      f_service_ << indent() << "return" << endl;
-      indent_down();
-      f_service_ << endl;
-      return;
+      f_service_ << indent() << "except Exception as ex:" << endl
+                 << indent() << "  msg_type = TMessageType.EXCEPTION" << endl
+                 << indent() << "  logging.exception(ex)" << endl
+                 << indent()
+                 << "  result = TApplicationException(TApplicationException.INTERNAL_ERROR, "
+                    "'Internal error')" << endl
+                 << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name()
+                 << "\", msg_type, seqid)" << endl
+                 << indent() << "result.write(oprot)" << endl
+                 << indent() << "oprot.writeMessageEnd()" << endl
+                 << indent() << "oprot.trans.flush()" << endl;
+    } else {
+      f_service_ << indent() << "except:" << endl
+                 << indent() << "  pass" << endl;
     }
 
-    f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name()
-               << "\", TMessageType.REPLY, seqid)" << endl << indent() << "result.write(oprot)"
-               << endl << indent() << "oprot.writeMessageEnd()" << endl << indent()
-               << "oprot.trans.flush()" << endl;
-
     // Close function
     indent_down();
     f_service_ << endl;