You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by yu...@apache.org on 2021/09/04 05:26:07 UTC

[thrift] branch 0.15.0 updated: THRIFT-5459: Fix breaking issue when adding a new exception

This is an automated email from the ASF dual-hosted git repository.

yuxuan pushed a commit to branch 0.15.0
in repository https://gitbox.apache.org/repos/asf/thrift.git


The following commit(s) were added to refs/heads/0.15.0 by this push:
     new 67bf304  THRIFT-5459: Fix breaking issue when adding a new exception
67bf304 is described below

commit 67bf304de18e025a768e21f1c39dd8aede882637
Author: Yuxuan 'fishy' Wang <yu...@reddit.com>
AuthorDate: Wed Sep 1 14:17:31 2021 -0700

    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.
---
 CHANGES.md                                         |  1 +
 compiler/cpp/src/thrift/generate/t_go_generator.cc | 18 +++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/CHANGES.md b/CHANGES.md
index 2f45c0d..746ec93 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 afed5ac..910eed3 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;