THRIFT-2343 Golang - Return a single error for all exceptions instead of multiple return values
Patch: Chris Bannister
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index f3d9100..29b1411 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -1686,13 +1686,6 @@
"value " << type_to_go_type((*f_iter)->get_returntype()) << ", ";
}
- t_struct* exceptions = (*f_iter)->get_xceptions();
- string errs = argument_list(exceptions);
-
- if (errs.size()) {
- f_service_ << errs << ", ";
- }
-
f_service_ <<
"err error) {" << endl;
indent_up();
@@ -1735,12 +1728,6 @@
indent() << " return" << endl <<
indent() << "}" << endl;
- // Careful, only return _result if not a void function
- if (!(*f_iter)->get_returntype()->is_void()) {
- f_service_ <<
- indent() << "value = " << result << ".Success" << endl;
- }
-
t_struct* xs = (*f_iter)->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
@@ -1751,8 +1738,21 @@
f_service_ <<
indent() << "if " << result << "." << pubname << " != nil {" << endl <<
- indent() << " " << varname << " = " << result << "." << pubname << endl <<
- indent() << "}" << endl;
+ indent() << "err = " << result << "." << pubname << endl <<
+ indent() << "return " << endl <<
+ indent() << "}";
+
+ if ((x_iter + 1) != xceptions.end()) {
+ f_service_ << " else ";
+ } else {
+ f_service_ << endl;
+ }
+ }
+
+ // Careful, only return _result if not a void function
+ if (!(*f_iter)->get_returntype()->is_void()) {
+ f_service_ <<
+ indent() << "value = " << result << ".Success" << endl;
}
f_service_ <<
@@ -2324,20 +2324,13 @@
indent() << "}" << endl <<
indent() << "iprot.ReadMessageEnd()" << endl <<
indent() << "result := New" << resultname << "()" << endl <<
+ indent() << "var err2 error" << endl <<
indent() << "if ";
if (!tfunction->is_oneway()) {
if (!tfunction->get_returntype()->is_void()) {
f_service_ << "result.Success, ";
}
-
- t_struct* exceptions = tfunction->get_xceptions();
- const vector<t_field*>& fields = exceptions->get_members();
- vector<t_field*>::const_iterator f_iter;
-
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- f_service_ << "result." << publicize(variable_name_to_go_name((*f_iter)->get_name())) << ", ";
- }
}
// Generate the function call
@@ -2345,7 +2338,7 @@
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
f_service_ <<
- "err = p.handler." << publicize(tfunction->get_name()) << "(";
+ "err2 = p.handler." << publicize(tfunction->get_name()) << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@@ -2358,24 +2351,41 @@
f_service_ << "args." << publicize(variable_name_to_go_name((*f_iter)->get_name()));
}
- f_service_ << "); err != nil {" << endl <<
+ f_service_ << "); err2 != nil {" << endl <<
+ indent() << "switch v := err2.(type) {" << endl;
+
+ t_struct* exceptions = tfunction->get_xceptions();
+ const vector<t_field*>& x_fields = exceptions->get_members();
+ vector<t_field*>::const_iterator xf_iter;
+
+ for (xf_iter = x_fields.begin(); xf_iter != x_fields.end(); ++xf_iter) {
+ f_service_ <<
+ indent() << " case *" << type_name((*xf_iter)->get_type()) << ":" << endl <<
+ indent() << "result." << publicize(variable_name_to_go_name((*xf_iter)->get_name())) << " = v" << endl;
+ }
+
+ f_service_ <<
+ indent() << " default:" << endl <<
indent() << " x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, \"Internal error processing " << escape_string(tfunction->get_name()) << ": \" + err.Error())" << endl <<
indent() << " oprot.WriteMessageBegin(\"" << escape_string(tfunction->get_name()) << "\", thrift.EXCEPTION, seqId)" << endl <<
indent() << " x.Write(oprot)" << endl <<
indent() << " oprot.WriteMessageEnd()" << endl <<
indent() << " oprot.Flush()" << endl <<
- indent() << " return" << endl <<
+ indent() << " return false, err2" << endl <<
+ indent() << "}" << endl;
+
+ f_service_ <<
indent() << "}" << endl <<
- indent() << "if err2 := oprot.WriteMessageBegin(\"" << escape_string(tfunction->get_name()) << "\", thrift.REPLY, seqId); err2 != nil {" << endl <<
+ indent() << "if err2 = oprot.WriteMessageBegin(\"" << escape_string(tfunction->get_name()) << "\", thrift.REPLY, seqId); err2 != nil {" << endl <<
indent() << " err = err2" << endl <<
indent() << "}" << endl <<
- indent() << "if err2 := result.Write(oprot); err == nil && err2 != nil {" << endl <<
+ indent() << "if err2 = result.Write(oprot); err == nil && err2 != nil {" << endl <<
indent() << " err = err2" << endl <<
indent() << "}" << endl <<
- indent() << "if err2 := oprot.WriteMessageEnd(); err == nil && err2 != nil {" << endl <<
+ indent() << "if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {" << endl <<
indent() << " err = err2" << endl <<
indent() << "}" << endl <<
- indent() << "if err2 := oprot.Flush(); err == nil && err2 != nil {" << endl <<
+ indent() << "if err2 = oprot.Flush(); err == nil && err2 != nil {" << endl <<
indent() << " err = err2" << endl <<
indent() << "}" << endl <<
indent() << "if err != nil {" << endl <<
@@ -3110,14 +3120,6 @@
}
}
- if (errs.size() > 0) {
- signature += errs;
-
- if (addError) {
- signature += ", ";
- }
- }
-
if (addError) {
signature += "err error";
}