summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuxuan 'fishy' Wang <yuxuan.wang@reddit.com>2021-09-01 14:17:31 -0700
committerYuxuan 'fishy' Wang <yuxuan.wang@reddit.com>2021-09-03 22:25:33 -0700
commit67bf304de18e025a768e21f1c39dd8aede882637 (patch)
treeb43537f3ab341078dcbbbffb2ebc92599aa7238c
parent5f829f143c40a125c611d03244b235a6d1a35d47 (diff)
downloadthrift-67bf304de18e025a768e21f1c39dd8aede882637.tar.gz
THRIFT-5459: Fix breaking issue when adding a new exception
Client: go Currently in the compiler generated go code, adding a new exception to an existing endpoint can cause unexpected behaviors when the client isn't updated. Fix the issue. Will be cherry-picked into 0.15.0 after merged.
-rw-r--r--CHANGES.md1
-rw-r--r--compiler/cpp/src/thrift/generate/t_go_generator.cc18
2 files changed, 18 insertions, 1 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 2f45c0d46..746ec93b0 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 afed5ac99..910eed398 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;