Failing promise gets catched by the Application.onerror function

150 Views Asked by At

There's this weird behavior which I don't know if it is supposed to be happening or it's a bug.

I'm using the WinJS.UI.Pages.render to render the content of a page under a specific element.

The problem I'm facing is that no matter if I handle the failing of the render function, the 'error' keeps propagating and it gets "catched" by the onerror function.

Here's a quick view of my code:

function goFunction() {
    WinJS.UI.Pages.render('otherpage.html', root).then(null, failedNavigating);
}

function noGoFunction() {
    WinJS.UI.Pages.render('missingpage.html', root).then(null, failedNavigating);
}

function failedNavigating() {
    console.log('failed to navigate');
}

WinJS.Application.onerror = function (args) {
    debugger;
};

The otherpage.html page exists so the rendering gets executed and everything is fine. But the missingpage.html does not exists. In that case the failedNavigating function executes, so far so good, but then the WinJS.Application.onerror handler gets 'called'.

Is that how that is supposed to work? What am I missing?

Here's a full project with a repro in case anybody wants to take a look at it.

3

There are 3 best solutions below

2
Xirzec On BEST ANSWER

I finally got around to debugging this in your GitHub issue. It's because WinJS.UI.Pages.render implicitly creates a Page, which by default has an error handler that creates an Error promise, which Application was detecting as an "unhandled error promise" since nothing was continuing off of it.

You can work around it for now with something like this:

function noGoFunction() {

    WinJS.UI.Pages.define('missingpage.html', {
        error: function (e) {
            console.log("Page failed to load");
        }

    });

    WinJS.UI.Pages.render('missingpage.html', root).then(null, failedNavigating);
}

function failedNavigating() {
    console.log('failed to navigate');
}
1
Maurizio In denmark On

Only the .done has the ability to catch and throw an error.

see here: http://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx for the differencies.

As you can see the two are almost identical apart from this: "After the handlers have finished executing, this function throws any error that would have been returned from then as a promise in the error state." that is only present in the .done.

Try to replace you .then with a .done and see if it works.

1
Maurizio In denmark On

Look at this: http://msdn.microsoft.com/en-us/library/windows/apps/br229728.aspx

promise.then(onComplete, onError, onProgress).done( /* Your success and error handlers */ );

onComplete

Type: function

The function to be called if the promise is fulfilled successfully with a value. The value is passed as the single argument. If the value is null, the value is returned. The value returned from the function becomes the fulfilled value of the promise returned by then. If an exception is thrown while this function is being executed, the promise returned by then moves into the error state.

So basically this happens because you have null in the onCompleted parameter of the .done

Try replacing it with a function instead