Question

I have this promise I simplified the code here but I can't get it to reject promise0. In example below, renameProfile first reads a file that holds all profile information, after reading it, it then tries to rename it which is done without promise. So in example readFile is success but rename file procedure fails. Yet it doesnt reject.

I am using Promise.jsm https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm

function doit() {
    var promise1 = renameProfile(1);
    promise1.then(
        function () {
            console.log('promise1 success');
        },
        function onReject(rsn) {
            console.log('promise1 failed rsn = ' + rsn);
        }
    );
    return promise1;
}

function renameProfile(readFileFirst) {
    if (readFileFirst == 1) {
        console.log('doing read file first');
        var promise2 = readFile();
        promise2.then(
            function () {
                console.log('promise2 success - read file success will now rename the profile');
                return renameProfile(0);
            },
            function (rsn) {
                console.log('promise2 failed - read file failed rsn = ' + rsn);
                return new Error('read file failed rsn = ' + rsn);
            }
        );
        return promise2;
    } else if (readFileFirst == 0) {
        //always reject promise
        console.log('doing renameProfile');
        return new Error('renameProfile failed');;
    }
}

function readFile() {
    let deferred = Promise.defer();
    deferred.resolve('successfully read file');
    return deferred.promise;
}

var promise0 = doit();
promise0.then(
    function () {
        console.log('promise0 success');
    },
    function (rsn) {
        console.log('promise0 failed rsn = ' + rsn);
    }
);
Was it helpful?

Solution 2

Well, the point about actually (re-)throwing errors was already made... But that is not the only thing wrong here... doIt() will return the result renameProfile(1), which is always promise2 = readFile() which is always successful.

What you meant to do would be to return not promise2 but promise2.then(...), which is another promise propagating the result or the promise2 callback(s).

Promise.then() returns:

A new promise that is initially pending, then assumes a state that depends on the outcome of the invoked callback function:

  • If the callback returns a value that is not a promise, including undefined, the new promise is fulfilled with this fulfillment value, even if the original promise was rejected.
  • If the callback throws an exception, the new promise is rejected with the exception as the rejection reason, even if the original promise was fulfilled.
  • If the callback returns a promise, the new promise will eventually assume the same state as the returned promise.

So here is how I'd correct the code:

function doit() {
    var promise1 = renameProfile(1);
    promise1.then(
        function () {
            console.log('promise1 success');
        },
        function onReject(rsn) {
            console.log('promise1 failed rsn = ' + rsn);
        }
    );
    return promise1;
}

function renameProfile(readFileFirst) {
    if (readFileFirst == 1) {
        console.log('doing read file first');
        var promise2 = readFile();
        // !!! return the right thing.
        return promise2.then(
            function () {
                console.log('promise2 success - read file success will now rename the profile');
                return renameProfile(0);
            },
            function (rsn) {
                console.log('promise2 failed - read file failed rsn = ' + rsn);
                throw new Error('read file failed rsn = ' + rsn);
            }
        );
    } else if (readFileFirst == 0) {
        //always reject promise
        console.log('doing renameProfile');
        throw new Error('renameProfile failed');
    }
}

function readFile() {
    let deferred = Promise.defer();
    deferred.resolve('successfully read file');
    return deferred.promise;
}

var promise0 = doit();
promise0.then(
    function () {
        console.log('promise0 success');
    },
    function (rsn) {
        console.log('promise0 failed rsn = ' + rsn);
    }
);

(promise1.then() is just for logging and has no effect on the outcome).

Resulting in

"doing read file first" Scratchpad/1:16
"promise2 success - read file success will now rename the profile" Scratchpad/1:20
"doing renameProfile" Scratchpad/1:30
"promise1 failed rsn = Error: renameProfile failed" Scratchpad/1:8
"promise0 failed rsn = Error: renameProfile failed" Scratchpad/1:47

OTHER TIPS

Promises work just like synchronous code - you can throw errors at will. In your case, you're returning an Error object, not throwing it.

throw new Error('renameProfile num == 2');

Should reject the promise and trigger your error handling.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top