A promise was created in a handler but was not ret

2020-04-12 16:20发布

问题:

I've just started using bluebird promises and am getting a confusing error

Code Abstract

var
  jQueryPostJSON = function jQueryPostJSON(url, data) {

    return Promise.resolve(
      jQuery.ajax({
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        type: "POST",
        url: url,
        data: JSON.stringify(data)
      })
    ).then(function(responseData) {
      console.log("jQueryPostJSON response " + JSON.stringify(responseData, null, 2));
      return responseData;
    });
  },
  completeTask = function completeTask(task, variables) {
    console.log("completeTask called for taskId: "+task.id);
    //FIXME reform variables according to REST API docs
    var variables = {
      "action" : "complete",
      "variables" : []
    };
    spin.start();
    return jQueryPostJSON(hostUrl + 'service/runtime/tasks/'+task.id, variables)
      .then(function() {
        gwl.grrr({
          msg: "Completed Task. Definition Key: " + task.taskDefinitionKey,
          type: "success",
          displaySec: 3
        });
        spin.stop();
        return null;
      });
  }

The jQueryPostJSON function seems to work fine as is when used else where, but in that case there is data returned from the server.

When it's used within complete task, the POST is successful as can be seen on the server side, but the then function is never called instead in the console I get the error

completeTask called for taskId: 102552
bundle.js:20945 spin target: [object HTMLDivElement]
bundle.js:20968 spinner started
bundle.js:1403 Warning: a promise was created in a  handler but was not returned from it
    at jQueryPostJSON (http://localhost:9000/dist/bundle.js:20648:22)
    at Object.completeTask (http://localhost:9000/dist/bundle.js:20743:14)
    at http://localhost:9000/dist/bundle.js:21051:15
From previous event:
    at HTMLDocument.<anonymous> (http://localhost:9000/dist/bundle.js:21050:10)
    at HTMLDocument.handleObj.handler (http://localhost:9000/dist/bundle.js:5892:30)
    at HTMLDocument.jQuery.event.dispatch (http://localhost:9000/dist/bundle.js:10341:9)
    at HTMLDocument.elemData.handle (http://localhost:9000/dist/bundle.js:10027:28)
bundle.js:1403 Unhandled rejection (<{"readyState":4,"responseText":"","sta...>, no stack trace)

The warning I get the reason for, that's not the issue. It's the Unhandled rejection and the fact that there was in fact no error from the POST.

line 21050 is here I am testing the combination of these to functions from separate modules

jQuery(document).bind('keydown', 'ctrl+]', function() {
        console.log("test key pressed");
        api.getCurrentProcessInstanceTask()
        .then(function(task) {
          api.completeTask(task);
        });

      });

Output from the first function call api.getCurrentProcessInstanceTask() seems to indicate it is working correctly, but here it is anyway

getCurrentProcessInstanceTask = function getCurrentProcessInstanceTask() {

      if (!currentProcess || !currentProcess.id) {
        return Promise.reject(new Error("no currentProcess is set, cannot get active task"));
      }

      var processInstanceId = currentProcess.id;

      return Promise.resolve(jQuery.get(hostUrl + "service/runtime/tasks", {
          processInstanceId: processInstanceId
        }))
        .then(function(data) {
          console.log("response: " + JSON.stringify(data, null, 2));
          currentProcess.tasks = data.data;
          // if(data.data.length > 1){
          //   throw new Error("getCurrentProcessInstanceTask expects single task result. Result listed "+data.data.length+" tasks!");
          // }
          console.log("returning task id: "+data.data[0].id);
          return data.data[0];
        });
    },

回答1:

You're getting the warning because you are - as it says - not returning the promise from the then handler.
Where the rejection is coming from would best be tracked by catching it and logging it. That there is no stack trace suggests that you (or one of the libs you use) is throwing a plain object that is not an Error. Try finding and fixing that.

Your call should look like this:

api.getCurrentProcessInstanceTask().then(function(task) {
    return api.completeTask(task);
//  ^^^^^^
}).catch(function(err) {
// ^^^^^
    console.error(err);
});