OpenCascade.js

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 fragmentLikely cause
Standard_OutOfRangeIndex past the end of an NCollection_* container
Standard_NullObjectMethod called on a null Handle<T> (forgot to check .IsNull())
Standard_NoSuchObjectMap lookup returned nothing
Standard_TypeMismatchDowncast 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 setForgot 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.

On this page