diff --git a/CHANGES.md b/CHANGES.md index 2f45c0d46a2..746ec93b0fd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -81,6 +81,7 @@ - [THRIFT-5404](https://issues.apache.org/jira/browse/THRIFT-5404) - TTransportException.Timeout would correctly return true when it's connect timeout during TSocket.Open call - [THRIFT-4797](https://issues.apache.org/jira/browse/THRIFT-4797) - The compiler now correctly auto renames import thrift namespaces when they collide with system imports - [THRIFT-5453](https://issues.apache.org/jira/browse/THRIFT-5453) - Defer DNS lookups from NewTSocketConf (without any timeout check) to TSocket.Open (subject to ConnectTimeout set in TConfiguration) +- [THRIFT-5459](https://issues.apache.org/jira/browse/THRIFT-5459) - Client calls will return TApplicationException with MISSING_RESULT when the result is a struct but is unset, and no other error is known. ### Haskell diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc index afed5ac9941..910eed39870 100644 --- a/compiler/cpp/src/thrift/generate/t_go_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc @@ -2295,7 +2295,23 @@ void t_go_generator::generate_service_client(t_service* tservice) { f_types_ << indent() << "}" << endl << endl; } - if (!(*f_iter)->get_returntype()->is_void()) { + if ((*f_iter)->get_returntype()->is_struct()) { + // Check if the result is nil, which likely means we have a new + // exception added but unknown to the client yet + // (e.g. client hasn't updated the thrift file). + // Sadly this check can only be reliable done when the return type is a + // struct in go. + std::string retName = tmp("_ret"); + f_types_ << indent() << "if " << retName << " := " << resultName + << ".GetSuccess(); " << retName << " != nil {" << endl; + indent_up(); + f_types_ << indent() << "return " << retName << ", nil" << endl; + indent_down(); + f_types_ << indent() << "}" << endl; + f_types_ << indent() << "return nil, " + << "thrift.NewTApplicationException(thrift.MISSING_RESULT, \"" + << method << " failed: unknown result\")" << endl; + } else if (!(*f_iter)->get_returntype()->is_void()) { f_types_ << indent() << "return " << resultName << ".GetSuccess(), nil" << endl; } else { f_types_ << indent() << "return nil" << endl;