BabylonJS / BabylonJS/JsRuntimeHost
Chakra napi shim: throws from class constructors are swallowed (don't surface to JS)
- Dominant language
- C++
- Stars
- 22
- Forks
- 23
- Avg merge
- 3d 14h
- Merged PRs (30d)
- 6
Description
On the Chakra backend, throwing a `Napi::TypeError` (or any Napi::Error) from a class constructor body — i.e. inside the function passed to `Napi::ObjectWrap` / `napi_define_class`'s callback — does not surface as a catchable JS exception. Instead the JS-side `new MyClass()` resolves to a half-constructed instance, so test code like `expect(() => new (File as any)()).to.throw()` silently fails.
This forces polyfills with required constructor arguments (WHATWG `File`, future `Request`, etc.) to either skip the WebIDL "missing required argument → TypeError" surface on Chakra, or omit the corresponding tests on Chakra.
### Repro
```cpp
class Foo : public Napi::ObjectWrap {
public:
static Napi::Function Init(Napi::Env env) {
return DefineClass(env, "Foo", {});
}
Foo(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) {
throw Napi::TypeError::New(info.Env(), "always throws");
}
};
```
In JS on Chakra: `expect(() => new Foo()).to.throw()` fails — no exception is thrown.
On V8 and JSC: throws as expected.
### Current workaround
In `Polyfills/File/Tests/UnitTests/Scripts/tests.ts` (introduced by #169), tests that assert the constructor throws on missing/invalid arguments are commented out with a TODO pointing here. They should be re-enabled atomically when this is fixed.
### Likely root cause
The Chakra napi shim's `ExternalCallback::Callback` (in `Core/Node-API/Source/js_native_api_chakra.cc`) probably needs to translate `env->last_exception` into a JsRT exception via `JsSetException` before returning to the JsRT runtime when invoked in construct mode. The function-call path likely already does this; the constructor path appears not to.
### Related
- JsRH#172 (separate JSC napi shim quirk).
- JsRH#169 (the PR that surfaced this).
Contributor guide
Assessment
This issue has not been assessed yet.