in compiler/cpp/src/thrift/generate/t_py_generator.cc [2045:2313]
void t_py_generator::generate_process_function(t_service* tservice, t_function* tfunction) {
(void)tservice;
// Open function
if (gen_tornado_) {
f_service_ << indent() << "@gen.coroutine" << '\n' << indent() << "def process_"
<< tfunction->get_name() << "(self, seqid, iprot, oprot):" << '\n';
} else {
f_service_ << indent() << "def process_" << tfunction->get_name()
<< "(self, seqid, iprot, oprot):" << '\n';
}
indent_up();
string argsname = tfunction->get_name() + "_args";
string resultname = tfunction->get_name() + "_result";
f_service_ << indent() << "args = " << argsname << "()" << '\n' << indent() << "args.read(iprot)"
<< '\n' << indent() << "iprot.readMessageEnd()" << '\n';
t_struct* xs = tfunction->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
// Declare result for non oneway function
if (!tfunction->is_oneway()) {
f_service_ << indent() << "result = " << resultname << "()" << '\n';
}
if (gen_twisted_) {
// Generate the function call
t_struct* arg_struct = tfunction->get_arglist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
f_service_ << indent() << "d = defer.maybeDeferred(self._handler." << tfunction->get_name()
<< ", ";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << "args." << (*f_iter)->get_name();
}
f_service_ << ")" << '\n';
if (tfunction->is_oneway()) {
f_service_ << indent() << "d.addErrback(self.handle_exception_" << tfunction->get_name()
<< ", seqid)" << '\n';
} else {
f_service_ << indent() << "d.addCallback(self.write_results_success_" << tfunction->get_name()
<< ", result, seqid, oprot)" << '\n'
<< indent() << "d.addErrback(self.write_results_exception_"
<< tfunction->get_name() << ", result, seqid, oprot)" << '\n';
}
f_service_ << indent() << "return d" << '\n' << '\n';
indent_down();
if (tfunction->is_oneway()) {
indent(f_service_) << "def handle_exception_" << tfunction->get_name()
<< "(self, error, seqid):" << '\n';
} else {
indent(f_service_) << "def write_results_success_" << tfunction->get_name()
<< "(self, success, result, seqid, oprot):" << '\n';
indent_up();
if (!tfunction->get_returntype()->is_void()) {
f_service_ << indent() << "result.success = success" << '\n';
}
f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name()
<< "\", TMessageType.REPLY, seqid)" << '\n'
<< indent() << "result.write(oprot)" << '\n'
<< indent() << "oprot.writeMessageEnd()" << '\n'
<< indent() << "oprot.trans.flush()" << '\n'
<< '\n';
indent_down();
indent(f_service_) << "def write_results_exception_" << tfunction->get_name()
<< "(self, error, result, seqid, oprot):" << '\n';
}
indent_up();
if (!tfunction->is_oneway()) {
f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n';
}
f_service_ << indent() << "try:" << '\n';
// Kinda absurd
f_service_ << indent() << indent_str() << "error.raiseException()" << '\n';
if (!tfunction->is_oneway()) {
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
const string& xname = (*x_iter)->get_name();
f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname
<< ":" << '\n';
indent_up();
f_service_ << indent() << "result." << xname << " = " << xname << '\n';
indent_down();
}
}
f_service_ << indent() << "except TTransport.TTransportException:" << '\n'
<< indent() << indent_str() << "raise" << '\n';
if (!tfunction->is_oneway()) {
f_service_ << indent() << "except TApplicationException as ex:" << '\n'
<< indent() << indent_str()
<< "logging.exception('TApplication exception in handler')" << '\n'
<< indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n'
<< indent() << indent_str() << "result = ex" << '\n'
<< indent() << "except Exception:" << '\n'
<< indent() << indent_str()
<< "logging.exception('Unexpected exception in handler')" << '\n'
<< indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n'
<< indent() << indent_str()
<< "result = TApplicationException(TApplicationException.INTERNAL_ERROR, "
"'Internal error')"
<< '\n'
<< indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name()
<< "\", msg_type, seqid)" << '\n'
<< indent() << "result.write(oprot)" << '\n'
<< indent() << "oprot.writeMessageEnd()" << '\n'
<< indent() << "oprot.trans.flush()" << '\n';
} else {
f_service_ << indent() << "except Exception:" << '\n'
<< indent() << indent_str()
<< "logging.exception('Exception in oneway handler')" << '\n';
}
indent_down();
} else if (gen_tornado_) {
// Generate the function call
t_struct* arg_struct = tfunction->get_arglist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
if (!tfunction->is_oneway()) {
indent(f_service_) << "msg_type = TMessageType.REPLY" << '\n';
}
f_service_ << indent() << "try:" << '\n';
indent_up();
f_service_ << indent();
if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
f_service_ << "result.success = ";
}
f_service_ << "yield gen.maybe_future(self._handler." << tfunction->get_name() << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << "args." << (*f_iter)->get_name();
}
f_service_ << "))" << '\n';
indent_down();
if (!tfunction->is_oneway()) {
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
const string& xname = (*x_iter)->get_name();
f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname
<< ":" << '\n'
<< indent() << indent_str() << "result." << xname << " = " << xname << '\n';
}
}
f_service_ << indent() << "except TTransport.TTransportException:" << '\n'
<< indent() << indent_str() << "raise" << '\n';
if (!tfunction->is_oneway()) {
f_service_ << indent() << "except TApplicationException as ex:" << '\n'
<< indent() << indent_str()
<< "logging.exception('TApplication exception in handler')" << '\n'
<< indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n'
<< indent() << indent_str() << "result = ex" << '\n'
<< indent() << "except Exception:" << '\n'
<< indent() << indent_str()
<< "logging.exception('Unexpected exception in handler')" << '\n'
<< indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n'
<< indent() << indent_str()
<< "result = TApplicationException(TApplicationException.INTERNAL_ERROR, "
"'Internal error')"
<< '\n';
} else {
f_service_ << indent() << "except Exception:" << '\n'
<< indent() << indent_str()
<< "logging.exception('Exception in oneway handler')" << '\n';
}
if (!tfunction->is_oneway()) {
f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name()
<< "\", msg_type, seqid)" << '\n'
<< indent() << "result.write(oprot)" << '\n'
<< indent() << "oprot.writeMessageEnd()" << '\n'
<< indent() << "oprot.trans.flush()" << '\n';
}
// Close function
indent_down();
} else { // py
// Try block for a function with exceptions
// It also catches arbitrary exceptions raised by handler method to propagate them to the client
f_service_ << indent() << "try:" << '\n';
indent_up();
// Generate the function call
t_struct* arg_struct = tfunction->get_arglist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
f_service_ << indent();
if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
f_service_ << "result.success = ";
}
f_service_ << "self._handler." << tfunction->get_name() << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << "args." << (*f_iter)->get_name();
}
f_service_ << ")" << '\n';
if (!tfunction->is_oneway()) {
f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n';
}
indent_down();
f_service_ << indent()
<< "except TTransport.TTransportException:" << '\n'
<< indent() << indent_str() << "raise" << '\n';
if (!tfunction->is_oneway()) {
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
const string& xname = (*x_iter)->get_name();
f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname
<< ":" << '\n';
indent_up();
f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n';
f_service_ << indent() << "result." << xname << " = " << xname << '\n';
indent_down();
}
f_service_ << indent() << "except TApplicationException as ex:" << '\n'
<< indent() << indent_str()
<< "logging.exception('TApplication exception in handler')" << '\n'
<< indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n'
<< indent() << indent_str() << "result = ex" << '\n'
<< indent() << "except Exception:" << '\n'
<< indent() << indent_str()
<< "logging.exception('Unexpected exception in handler')" << '\n'
<< indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n'
<< indent() << indent_str()
<< "result = TApplicationException(TApplicationException.INTERNAL_ERROR, "
"'Internal error')"
<< '\n'
<< indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name()
<< "\", msg_type, seqid)" << '\n'
<< indent() << "result.write(oprot)" << '\n'
<< indent() << "oprot.writeMessageEnd()" << '\n'
<< indent() << "oprot.trans.flush()" << '\n';
} else {
f_service_ << indent() << "except Exception:" << '\n'
<< indent() << indent_str() << "logging.exception('Exception in oneway handler')" << '\n';
}
// Close function
indent_down();
}
}