Skip to content

web-worker should postMessage sql-errors (instead of throwing) #293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

kaizhu256
Copy link
Member

chrome, edge, (firefox?) do not seem to honor worker.onerror -- and without some kind of error-feedback from sql.js web-workers, they are unsuitable for production use in many browser scenarios.

this [demonstration] patch provides a bug-workaround by postMessaging back errmsg (rather than throwing it).

here's a fully working standalone html-code for patched worker.sql-wasm-debug (with screenshot):

image

<script>
/* jslint utility2:true */
(async function () {
    "use strict";
    var callbackCount;
    var callbackDict;
    var worker;
    var workerPostMessage;
    callbackCount = 0;
    callbackDict = {};
    worker = new Worker("assets.sqljs.js");
    worker.addEventListener("message", function (msg) {
    /*
     * this function will dispatch received <msg>.data to <callback>
     */
        var callback;
        callback = callbackDict[msg.data.id];
        delete callbackDict[msg.data.id];
        if (callback) {
            callback(msg.data);
        }
    });
    workerPostMessage = function (msg) {
    /*
     * this function will return a promise to postMessage <opt> to worker
     */
        var callback;
        var err;
        // preserve stack-trace outside of [async] Promise for debugging
        err = new Error();
        return new Promise(function (resolve, reject) {
            callback = function (data) {
                // handle errmsg
                if (data.errmsg) {
                    err.message = data.errmsg;
                    reject(err);
                    return;
                }
                // handle data
                resolve(data);
            };
            // save callback in callbackDict
            callbackCount += 1;
            msg.id = callbackCount;
            callbackDict[msg.id] = callback;
            // postMessage with id
            worker.postMessage(msg);
        });
    };
    // test worker data-handling
    console.log(await workerPostMessage({
        action: "exec",
        sql: "SELECT 1"
    }));
    // test worker err-handling
    try {
        await workerPostMessage({
            action: "exec",
            sql: "syntax error"
        });
    } catch (errCaught) {
        console.error(errCaught.stack);
        window.alert(
            "caught web-worker error\n" + errCaught.stack
        );
    }
}());
</script>

chrome, edge, (firefox?) do not seem to honor worker.onerror -- and without some kind of error-feedback from sql.js web-workers, they are unsuitable for production use in many browser scenarios.

this patch provides a bug-workaround by postMessaging back `errmsg` (rather than throwing it).

here's a fully working standalone html-code for patched worker.sql-wasm-debug (with screenshot):

```html
<script>
/* jslint utility2:true */
(async function () {
    "use strict";
    var callbackCount;
    var callbackDict;
    var worker;
    var workerPostMessage;
    callbackCount = 0;
    callbackDict = {};
    worker = new Worker("assets.sqljs.js");
    worker.addEventListener("message", function (msg) {
    /*
     * this function will dispatch received <msg>.data to <callback>
     */
        var callback;
        callback = callbackDict[msg.data.id];
        delete callbackDict[msg.data.id];
        if (callback) {
            callback(msg.data);
        }
    });
    workerPostMessage = function (msg) {
    /*
     * this function will return a promise to postMessage <opt> to worker
     */
        var callback;
        var err;
        // preserve stack-trace outside of [async] Promise for debugging
        err = new Error();
        return new Promise(function (resolve, reject) {
            callback = function (data) {
                // handle errmsg
                if (data.errmsg) {
                    err.message = data.errmsg;
                    reject(err);
                    return;
                }
                // handle data
                resolve(data);
            };
            // save callback in callbackDict
            callbackCount += 1;
            msg.id = callbackCount;
            callbackDict[msg.id] = callback;
            // postMessage with id
            worker.postMessage(msg);
        });
    };
    // test worker data-handling
    console.log(await workerPostMessage({
        action: "exec",
        sql: "SELECT 1"
    }));
    // test worker err-handling
    try {
        await workerPostMessage({
            action: "exec",
            sql: "syntax error"
        });
    } catch (errCaught) {
        console.error(errCaught.stack);
        window.alert(
            "caught web-worker error\n" + errCaught.stack
        );
    }
}());
</script>
```
@lovasoa
Copy link
Member

lovasoa commented Sep 9, 2019

See #288

@lovasoa lovasoa closed this Sep 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants