Question: What data type does one use to pass a JavaScript Error object to a WinRT component?

Answer: None, actually. You cannot directly pass an Error object to native code in a component, as that object type won’t be meaningful in C++. You could stringify the Error and pass it as JSON, but that’s something of a pain.

What you can do instead is to source an exception in C++ (or C#), where those exceptions have known HRESULTs, because then you’ll get the appropriate errors in JavaScript thanks to the projection layer. It does take a little extra time (very small) to marshal this exception across the layer boundaries, but would only matter if you end up throwing millions of exceptions per second. (I hope that’s not the case!)

Here’s a C++ example to generate an Access Denied (E_ACCESSDENIED) that’s usable across the component boundary:

class ErrorHelper
{
public:
static void ThrowAccessDenied();
}

ErrorHelper::ThrowAccessDenied()
{
throw ref new Platform::AccessDeniedException();
}

And clearly you can extend ErrorHelper to include other methods for additional errors you need to use.

Thanks to Rob Paveza for this solution.

 


I was following a thread recently where a dev was trying to track down an app crash. In this case he had a window.onerror handler set up but it wasn’t being called.

The bottom line in the thread was that if any exception is thrown within the context of a WinJS.Application event, such as onactivated, then it will be picked up only by a WinJS.Application.onerror handler and not window.onerror. On the other hand, exceptions that are thrown in any other function context, e.g. the callback to a setTimeout or a button click handler, will be picked up by window.onerror as well as by WinJS.Application.onerror, which wraps window.onerror.

Consider the following bit of code in an otherwise blank app project:

(function () {
​   
var app = WinJS.Application;

​   
app.onactivated = function (args) {
​      
throw (“Error from on activated”);
    };

    app.onerror = function (e) {
        console.log(“WinJS.Application.onerror e = “ + e.detail.errorMessage);
        returntrue;
    }

    window.onerror = function (e) {
​       
console.log(“window.onerror e = “ + e)
        returntrue;
​   
}

    app.start();

    throw (“Error outside of WinJS.Application.”);
})();

Running this code, Visual Studio will call out the exception from the last throw. Pressing Continue you’ll get to window.onerror, followed by app.onerror. You’ll then get into app.onactivated, where that thrown exception will then take you to app.onerror but not window.onerror.