Debugging wasm exceptions
Decode WebAssembly.Exception into actionable error messages with getExceptionMessage.
When OCCT throws a Standard_Failure inside the wasm module, the value that
reaches your JS try/catch is a WebAssembly.Exception object. Printing it
with console.error(error) yields [object WebAssembly.Exception] — useless.
@taucad/opencascade.js@beta exposes getExceptionMessage(error) to decode
the C++ failure into a string.
The pattern
import init, { getExceptionMessage } from '@taucad/opencascade.js';
const oc = await init({ locateFile });
try {
using fillet = new oc.BRepFilletAPI_MakeFillet(badShape);
fillet.Shape(); // may throw
} catch (error: unknown) {
if (error instanceof WebAssembly.Exception) {
console.error('OCCT failure:', getExceptionMessage(error));
} else {
throw error;
}
}getExceptionMessage reaches into the wasm-side Standard_Failure::GetMessageString()
and returns the text OCCT actually attached to the exception (e.g.
"BRepFilletAPI_MakeFillet: Empty argument").
Why not just error.message?
WebAssembly.Exception is a JS host object — its message field is empty for
C++-thrown values. The actual text lives in C++ memory, addressable only by
walking back into the wasm module.
Common OCCT exceptions
| Message fragment | Likely cause |
|---|---|
Standard_OutOfRange | Index past the end of an NCollection_* container |
Standard_NullObject | Method called on a null Handle<T> (forgot to check .IsNull()) |
Standard_NoSuchObject | Map lookup returned nothing |
Standard_TypeMismatch | Downcast to the wrong TopoDS_* subtype |
BRepAlgoAPI_*: ... | Boolean failure — usually self-intersecting input |
BRepFilletAPI_MakeFillet: ... | Fillet radius too large, or degenerate edge |
STEPControl_Writer: write.step.schema not set | Forgot Interface_Static.SetIVal('write.step.schema', 5) |
Async-safe pattern
If your call site awaits between the try and the throw, wrap the offending
synchronous block tightly:
const filletShape = await runOcctSync(() => {
using fillet = new oc.BRepFilletAPI_MakeFillet(shape);
for (const edge of edges) fillet.Add(3, edge);
return fillet.Shape();
});Wide async try/catch boundaries swallow the WebAssembly.Exception type
discriminator on some engines.
Debug builds
For deep debugging, build with -g -fwasm-exceptions -O1 and load
Chrome's wasm DWARF debugger.
You get the original C++ frames in the call stack — invaluable when an OCCT
exception originates ten frames deep in BOPAlgo_PaveFiller.