Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

WebAssembly.Exception

Baseline
Weitgehend verfügbar
*

Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Mai 2022 browserübergreifend verfügbar.

* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.

Hinweis: Diese Funktion ist in Web Workers verfügbar.

Das WebAssembly.Exception-Objekt repräsentiert eine Laufzeitausnahme, die in einem Wasm-Modul ausgelöst wird.

Konstruktor

WebAssembly.Exception()

Erstellt eine neue Instanz des WebAssembly.Exception-Objekts.

Instanzeigenschaften

Exception.prototype.stack

Gibt den Stack-Trace der Ausnahme zurück.

Instanzmethoden

Exception.prototype.is()

Prüft, ob die Ausnahme mit einem bestimmten Tag übereinstimmt.

Exception.prototype.getArg()

Gibt die Datenfelder einer Ausnahme zurück, die mit einem angegebenen Tag übereinstimmt.

Beschreibung

Wenn Wasm-Ausnahmen im JavaScript-Host behandelt werden, haben abgefangene Ausnahmen den Objekttyp WebAssembly.Exception.

Sie können beispielsweise zunächst mit dem Konstruktor WebAssembly.Tag() einen Fehler-Tag-Typ erstellen:

js
const myErrorTag = new WebAssembly.Tag({ parameters: ["i32"] });

Anschließend können Sie ihn wie folgt in ein Wasm-Modul importieren:

js
const env = {
  my_error: myErrorTag,
};

WebAssembly.instantiateStreaming(fetch("module.wasm"), { env }).then(/* ... */);

Danach können Sie versuchen, eine exportierte Wasm-Funktion in einer try...catch-Anweisung auszuführen. Wenn die Funktion eine Ausnahme auslöst, ist der an den catch-Block weitergegebene Fehler eine Instanz des WebAssembly.Exception-Objekts.

js
WebAssembly.instantiateStreaming(fetch("module.wasm"), { env }).then(
  (result) => {
    try {
      // Cause function to throw
      result.instance.exports.throw(-1);
    } catch (e) {
      if (e instanceof WebAssembly.Exception && e.is(myErrorTag)) {
        const errorCode = e.getArg(myErrorTag, 0); // 0 = first payload value
        console.log("Error code:", errorCode); // 42
      } else {
        throw e; // throw other errors
      }
    }
  },
);

Mit Exception.prototype.is() können Sie prüfen, ob die Ausnahme denselben Typ wie der zuvor definierte Tag (myErrorTag) hat. Anschließend können Sie mit Exception.prototype.getArg() auf die Nutzdaten der Ausnahme zugreifen.

JavaScript und anderer Client-Code können nur dann auf WebAssembly-Ausnahmewerte zugreifen – und umgekehrt –, wenn der zugehörige Tag gemeinsam verwendet wird. Sie können nicht einfach einen anderen Tag verwenden, der zufällig dieselben Datentypen definiert. Ohne den passenden Tag können Ausnahmen abgefangen und erneut ausgelöst, aber nicht untersucht werden.

Damit Ausnahmen schneller ausgelöst werden können, enthalten Ausnahmen aus WebAssembly im Allgemeinen keinen Stack-Trace. WebAssembly-Code, der einen Stack-Trace bereitstellen muss, muss zum Erstellen der Ausnahme eine JavaScript-Funktion aufrufen und dabei im Konstruktor den Parameter options.traceStack=true übergeben. Der Konstruktor kann dann eine Ausnahme zurückgeben, deren Eigenschaft stack einen Stack-Trace enthält.

Beispiele

Dieses Beispiel zeigt, wie Sie einen Tag definieren und in ein Modul importieren. Anschließend wird damit eine Ausnahme ausgelöst, die in JavaScript abgefangen wird.

Betrachten Sie den folgenden WebAssembly-Code, der in eine Datei namens example.wasm kompiliert wurde.

  • Das Modul importiert einen Tag, der intern als $tagname bezeichnet wird und einen einzelnen i32-Parameter hat. Der Tag muss über das Modul extmod und den Tag exttag übergeben werden.
  • Die Funktion $throwException löst mit der Anweisung throw eine Ausnahme aus und verwendet dabei $tagname und das Parameterargument.
  • Das Modul exportiert die Funktion run(), die eine Ausnahme mit dem Wert „42“ auslöst.
wat
(module
  ;; import tag that will be referred to here as $tagname
  (import "extmod" "exttag" (tag $tagname (param i32)))

  ;; $throwException function throws i32 param as a $tagname exception
  (func $throwException (param $errorValueArg i32)
    local.get $errorValueArg
    throw $tagname
  )

  ;; Exported function "run" that calls $throwException
  (func (export "run")
    i32.const 42
    call $throwException
  )
)

Der folgende Code ruft WebAssembly.instantiateStreaming auf, um die Datei example.wasm zu importieren. Dabei übergibt er ein „Importobjekt“ (importObject), das einen neuen WebAssembly.Tag namens tagToImport enthält. Das Importobjekt definiert ein Objekt mit Eigenschaften, die der import-Anweisung im WebAssembly-Code entsprechen.

Sobald die Datei instanziiert wurde, ruft der Code die exportierte WebAssembly-Methode run() auf, die sofort eine Ausnahme auslöst.

js
const tagToImport = new WebAssembly.Tag({ parameters: ["i32"] });

// Note: import object properties match the WebAssembly import statement!
const importObject = {
  extmod: {
    exttag: tagToImport,
  },
};

WebAssembly.instantiateStreaming(fetch("example.wasm"), importObject)
  .then((obj) => {
    console.log(obj.instance.exports.run());
  })
  .catch((e) => {
    console.error(e);
    // Check we have the right tag for the exception
    // If so, use getArg() to inspect it
    if (e.is(tagToImport)) {
      console.log(`getArg 0 : ${e.getArg(tagToImport, 0)}`);
    }
  });

/* Log output
example.js:40 WebAssembly.Exception: wasm exception
example.js:41 getArg 0 : 42
*/

Die Ausnahme wird in JavaScript im catch-Block abgefangen. Sie ist vom Typ WebAssembly.Exception. Ohne den richtigen Tag könnten wir jedoch kaum etwas Weiteres damit anfangen.

Da wir den Tag haben, prüfen wir mit Exception.prototype.is(), ob es der richtige ist. Da dies der Fall ist, lesen wir mit Exception.prototype.getArg() den Wert „42“ aus.

Spezifikationen

Spezifikation
WebAssembly JavaScript Interface: Exception Handling
# runtime-exceptions

Browser-Kompatibilität

Siehe auch