L. Cornelius Dol
L. Cornelius Dol

Reputation: 64036

ReferenceError from within Mithril promise chain is being silently ignored

I am using Firefox 32 and Chrome 37 with Mithril.js and have now been repeatedly tripped up by typos in variable names just silently causing the JS to stop executing at the point of the reference. It's particularly frustrating for me coming from C and Java since I am used to the compiler catching such trivial mistakes before I even attempt to run the code.

I have narrowed down the problem to be occurring only in functions running as part of the AJAX promise chain, like this:

function getListData(ctl) {
    ctl.data([]);
    ctl.loading(true);
    return m.request({ method: "GET", url: apiBase, background: true }).then(done,fail);

    function done(rspdta) {
        xctl.loading(false);
        ctl.data(rspdta.Customer);
        m.redraw();
        };

    function fail(rspdta) {
        ctl.loading(false);
        ajaxError(ctl);
        m.redraw();
        throw rspdta;                                                                               // continue error condition
        };
    }

Notice the deliberate xctl.loading(false) in the done function -- the script just appears to stop there, but a ReferenceError is thrown. However, nothing is logged.

I am working on how to prove have proved that it's being caught and ignored by Mithril.js now, in this code:

function thennable (ref, cb, ec, cn) {
    if ((typeof val == 'object' || typeof val == 'function') && typeof ref == 'function') {
        try {

            // cnt protects against abuse calls from spec checker
            var cnt = 0
            ref.call(val, function (v) {
                if (cnt++) return
                val = v
                cb()
            }, function (v) {
                if (cnt++) return
                val = v
                ec()
            })
        } catch (e) {
            /**/console.log("[**] Caught in thennable: %o",e);
            val = e
            ec()
        }
    } else {
        cn()
    }
};

Hopefully someone from that community will be able to say whether I've done something wrong, am misusing the promise chain (??) or if it's a bug in Mithril.js 0.1.21.

Upvotes: 2

Views: 587

Answers (2)

LeoHorie
LeoHorie

Reputation: 1320

Long story short, it's a problem in the Promises/A+ spec (basically it doesn't differentiate between checked and unchecked errors). For Mithril 0.1.21 (and for that matter, for native ES6 Promises), the workaround to catch the error is to do what Zolmeister said.

.then(buggyCallback) //this throws the ReferenceException
.then(null, function(e) {console.error(e)})

Alternatively, Mithril 0.1.19 (the last version before the Promiz PR merge) throws to console by default.

Mithril 0.1.22 will ship with a promise exception monitor that will allow you to configure how to early-catch promise exceptions (and will default to throwing to the console for programmer errors). You can find this version in the development repo.

Upvotes: 2

Zolmeister
Zolmeister

Reputation: 224

Errors thrown inside an onFulfilled handler result in a rejected promise. Spec: http://promisesaplus.com/#point-42

Here is the solution:

abc.then(thrower, fail1).then(null, fail2)

It will be caught by fail2

Upvotes: 1

Related Questions