C++ Exceptions Support

By default, exception catching is disabled in Emscripten. For example, if you compile the following program:

#include <stdio.h>

int main() {
  try {
    puts("throw...");
    throw 1;
    puts("(never reached)");
  } catch(...) {
    puts("catch!");
  }
  return 0;
}

The first throw will abort the program and you’ll see something like this in the output:

throw...
exception thrown: 5246024 - Exception catching is disabled, this exception cannot be caught. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch.

If you want to opt-in, you have two following options.

JavaScript-based Exception Support

First, you can enable exceptions via Emscripten’s JavaScript-based support. To enable it, pass -fexceptions at both compile time and link time.

When you rebuild the example above with this flag, the output will change to:

throw...
catch!

Note that this option has relatively high overhead, but it will work on all JavaScript engines with WebAssembly support. You can reduce the overhead by specifying a list of allowed functions in which exceptions are enabled, see the EXCEPTION_CATCHING_ALLOWED setting.

WebAssembly Exception Handling-based Support

Alternatively, you can opt-in to the native WebAssembly exception handling proposal. To enable it, pass -fwasm-exceptions at both compile time and link time.

Rebuilding the example with this flag will result in the same output as with -fexceptions above:

throw...
catch!

This option leverages a new feature that brings built-in instructions for throwing and catching exceptions to WebAssembly. As a result, it can reduce code size and performance overhead compared to the JavaScript-based implementation. This option is currently supported in several major web browsers, but may not be supported in all WebAssembly engines yet.

Debugging Exceptions

When ASSERTIONS is enabled, uncaught exceptions will print stack traces for debugging. ASSERTIONS is enabled by default in -O0 and disabled in optimized builds (-O1 and above). You can enable it by passing -sASSERTIONS to the emcc command line in optimized builds as well.

You can also catch and examine C++ exceptions from JavaScript. See Handling C++ exceptions from JavaScript.

Using Exceptions and setjmp-longjmp Together

See Using Exceptions and setjmp-longjmp Together.