Skip to content

Commit

Permalink
THRIFT-5459: Fix breaking issue when adding a new exception
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
fishy committed Sep 4, 2021
1 parent 5f829f1 commit 67bf304
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 17 additions & 1 deletion compiler/cpp/src/thrift/generate/t_go_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 67bf304

Please sign in to comment.