Uploaded image for project: 'Thrift'
  1. Thrift
  2. THRIFT-5674

Server implementation exceptions are not sent to client in ES6 promise-style invocation

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 0.17.0
    • 0.19.0
    • JavaScript - Compiler
    • None
    • Discovered on Node.js v16.13.2, Thrift 0.17.0 compiler, 0.16.0 library.

      Reproduced on Node.js v10.19.0, Thrift 0.17.0 compiler, 0.17.0 library (just what I happened to have available for trying out the tutorial code).

    Description

      When a server implementation throws a user-defined exception, the server crashes and the exception is not sent to the client.  I believe this issue only happens in the Promise-style invocation of code generated for ES6.  Specifically, I think it arises from this line:

      https://github.com/apache/thrift/blob/0.17.0/compiler/cpp/src/thrift/generate/t_js_generator.cc#L1484

      Generated code looks like the following (generated from the Calculator.calculate example):

      Promise.resolve(this._handler.calculate.bind(this._handler)(
        args.logid,
        args.w
      )).then(
        ...
      ).catch(err => {
        if (err instanceof ttypes.InvalidOperation) {
          ...
        }
      );

      The implementation-generated exception is handled by the promise chain.  The problem is that the implementation (handler) method is called before Promise.resolve, so any exception it throws is not handled by the promise chain.  So, when running1 NodeServerPromise.js and NodeClientPromise.js from the tutorial, the server crashes when InvalidOperation is thrown and the client does not receive InvalidOperation (or anything further).

      I think the minimal fix would be to generate something like the following instead:

      new Promise((resolve) => resolve(this._handler.calculate.bind(this._handler)(
        args.logid,
        args.w
      ))).then(
        ...
      ).catch(err => {
        if (err instanceof ttypes.InvalidOperation) {
          ...
        }
      );

      When making this change on the generated tutorial code and re-running1 the server and client, the server stays up and both the server and client log five lines, as expected.

      [1] There also seems to be a couple of errors in NodeClientPromise.js in the tutorial code.  I had to change "fail" to "catch" and "fin" to "finally" to get it to work.

      Attachments

        Issue Links

          Activity

            People

              cjmay Chandler May
              cjmay Chandler May
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - 3h
                  3h
                  Remaining:
                  Time Spent - 20m Remaining Estimate - 2h 40m
                  2h 40m
                  Logged:
                  Time Spent - 20m Remaining Estimate - 2h 40m
                  20m