How do I handle JS runtime errors in Guile Hoot?

How do I handle errors thrown from the browser runtime?

In main.js, I have some JS code which may throw an error. To test error handling from Scheme, I just throw an error myself:

navigator: {
  requestWakeLock: () => {
    // navigator.wakeLock.request("screen")
    throw new Error('FAIL');
  }

In dom/modules/navigator.scm:

(define-foreign request-wake-lock
  "navigator" "requestWakeLock"
  -> (ref extern))

In main.scm, I wrap the code which I expect to throw an error in with-exception-handler according to the hoot manual (I think):

(with-exception-handler
    (lambda (exn)
      (format (current-error-port)
              "Wake Lock could not be set: ~s\n" exn)
      #f)
  (lambda () (await (request-wake-lock))))

In the browser console, I see:

Uncaught (in promise) Error: FAIL
    requestWakeLock http://localhost:8088/main.js:82
    call http://localhost:8088/reflect.js:380
    call http://localhost:8088/reflect.js:118
    #init_module http://localhost:8088/reflect.js:280
    load_main http://localhost:8088/reflect.js:285
    async* http://localhost:8088/main.js:3
    EventListener.handleEvent* http://localhost:8088/main.js:1
main.js:82:19
    <anonymous> http://localhost:8088/main.js:118
    AsyncFunctionThrow self-hosted:804
    (Async: async)
    <anonymous> http://localhost:8088/main.js:1

which is the same error I get if I don’t wrap it in with-exception-handler:

(await (request-wake-lock))

Advice very much appreciated!

Thank you,

Joseph

JS errors are not Scheme errors, so you cannot catch them from within Scheme.

Speaking more generally, WebAssembly has its own notion of exceptions. In order for an exception to propagate from JS into Wasm, the WebAssembly.Exception type needs to be used and it needs to reference a WebAssembly.Tag that the Wasm binary understands and can catch.

Now back to Hoot. Hoot has its own exception system that is distinct from WebAssembly’s because the Scheme call stack is just a different beast. What we could think about adding is a special Wasm tag for all foreign exceptions. The Hoot runtime could catch exceptions of that tag and throw a &foreign Scheme exception or something.

For right now I recommend returning special values to indicate errors and then throw Scheme exceptions accordingly.

1 Like

Thank you for the explanation. For now, I’ll catch the error in JS and return a special value to catch in Scheme.

1 Like