code: function createAPIDoneHook(done, ctx) {
      let hookInfo = {
          resData: null,
          resException: false,
          hook: null
      };
  
      hookInfo.hook = (err, res, complete, shouldCatchException) => {
          let result;
          if (err != null) {
              result = err;
              if (shouldCatchException) {
                  try {
                      let data = done(result, null, ctx);
                      data == null || (result = data);
                  }
                  catch (ex) {
                      // cache exception info for promise
                      hookInfo.resException = true;
                      result = ex;
                  }
              }
              else {
                  let data = done(result, null, ctx);
                  data == null || (result = data);
              }
          }
          else {
              let data = done(null, res, ctx);
              data == null || (res = data);
              result = res;
          }
  
          // cache response data for promise
          hookInfo.resData = result;
  
          complete && complete(result); // call complete callback
  
          return result;
      };
  
      return hookInfo;
  }
docs: Crate API done hook
  
  @inner
  @param {Function} done the done hook to execute
  @param {Object} ctx the extra call context for the hook
  @return {Object}