Signatur
Beschreibung
WebGPU meldet die meisten Fehler asynchron. Eine ungültige Pipeline-Beschreibung oder ein fehlgeschlagener Puffer-Zugriff löst also keine Ausnahme aus. Stattdessen wird ein Fehlerobjekt erzeugt, und das betroffene Objekt wird intern als ungültig markiert. Mit pushErrorScope() öffnen Sie einen Fehlerbereich, der Fehler eines bestimmten Typs sammelt. Später schließen Sie ihn mit GPUDevice.popErrorScope(). Das liefert ein Promise, das mit dem ersten abgefangenen Fehler erfüllt wird oder mit null, wenn kein Fehler aufgetreten ist.
Fehlerbereiche bilden einen Stapel (Stack) und lassen sich verschachteln. Ein Fehler landet immer im innersten Bereich, dessen Filter zum Fehlertyp passt. Passt kein Bereich auf dem Stapel, wird der Fehler als uncapturederror-Ereignis am GPUDevice ausgelöst. Der Browser gibt dann in der Regel auch eine Warnung in der Konsole aus.
Typische Einsatzfälle:
- Beim Erstellen von Shader-Modulen oder Pipelines gezielt Validierungsfehler abfangen, zum Beispiel bei nutzergeneriertem WGSL-Code.
- Bei großen Puffern oder Texturen prüfen, ob ein
out-of-memory-Fehler auftritt, um dann auf kleinere Ressourcen auszuweichen. - Beim Debugging einzelne Codeabschnitte eingrenzen, um herauszufinden, welcher Aufruf einen Fehler verursacht.
Jeder pushErrorScope()-Aufruf braucht genau einen passenden popErrorScope()-Aufruf.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $filter Pflicht | "validation" | "out-of-memory" | "internal" | Legt fest, welcher Fehlertyp abgefangen wird:
|
Rückgabewert
Promise von popErrorScope().Beispiele
Validierungsfehler beim Erstellen eines Shader-Moduls abfangen
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
device.pushErrorScope('validation');
// Absichtlich fehlerhafter WGSL-Code (Tippfehler bei 'vec4f')
const module = device.createShaderModule({
code: `@fragment fn main() -> @location(0) vec4g { return vec4f(1.0); }`
});
const error = await device.popErrorScope();
if (error) {
console.error('Shader ungültig:', error.message);
} else {
console.log('Shader erfolgreich kompiliert');
}
Speichermangel bei großem Puffer erkennen und auf kleineren Puffer ausweichen
const createBufferSafe = async (device, size) => {
device.pushErrorScope('out-of-memory');
const buffer = device.createBuffer({
size,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
});
const error = await device.popErrorScope();
if (error) {
buffer.destroy();
return null;
}
return buffer;
};
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const size = 256 * 1024 * 1024; // 256 MiB
const buffer = (await createBufferSafe(device, size))
?? (await createBufferSafe(device, size / 4));
console.log(buffer ? `Puffer mit ${buffer.size} Bytes angelegt` : 'Kein Speicher verfügbar');
Verschachtelte Fehlerbereiche und uncapturederror als Auffangnetz
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
// Auffangnetz für alle Fehler ohne passenden Bereich
device.addEventListener('uncapturederror', (event) => {
console.warn('Nicht abgefangen:', event.error.message);
});
device.pushErrorScope('out-of-memory'); // äußerer Bereich
device.pushErrorScope('validation'); // innerer Bereich
// Ungültig: Größe 3 ist kein Vielfaches von 4 bei mappedAtCreation
device.createBuffer({ size: 3, usage: GPUBufferUsage.VERTEX, mappedAtCreation: true });
// popErrorScope() in umgekehrter Reihenfolge aufrufen: der innerste Bereich zuerst
const [validationError, oomError] = await Promise.all([
device.popErrorScope(),
device.popErrorScope()
]);
console.log('Validierung:', validationError?.constructor.name ?? 'keiner');
console.log('Speicher:', oomError?.constructor.name ?? 'keiner');
// Wichtig · Fallstricke
- Nur der erste Fehler zählt: Ein Bereich speichert nur den ersten passenden Fehler. Alle weiteren Fehler in diesem Bereich werden verworfen und auch nicht an äußere Bereiche oder an
uncapturederrorweitergereicht. - Gleichgewicht einhalten: Jeder
pushErrorScope()braucht einpopErrorScope(). Ist der Stapel leer, wird das Promise vonpopErrorScope()mit einemOperationErrorabgelehnt. Das passiert zum Beispiel, wenn Sie einmal zu oftpopErrorScope()aufrufen. - Kein Ersatz für try/catch: Fehler werden asynchron gemeldet. Ein
try/catchumcreateBuffer()fängt Validierungsfehler nicht ab. Ausnahmen gibt es nur bei direkt geprüften Fällen, z. B. ungültigen Enum-Werten (TypeError). - Ungültiger Filter: Ein anderer String als
\"validation\",\"out-of-memory\"oder\"internal\"löst sofort einenTypeErroraus. - Performance:
popErrorScope()wartet auf die GPU. Fehlerbereiche in Render-Schleifen, also bei jedem Frame, kosten spürbar Leistung. Setzen Sie sie gezielt bei der Initialisierung oder beim Debugging ein. - Geltungsbereich: Der Fehlerbereichs-Stapel wird pro Gerät verwaltet. In Chromium betrifft er nur Aufrufe aus derselben JavaScript-Ausführung. Aufrufe innerhalb von Callbacks anderer asynchroner Abläufe können daher in einem anderen Bereich landen als erwartet.
- Kompatibilität: WebGPU gibt es nur in sicheren Kontexten (HTTPS). Chrome und Edge unterstützen es ab Version 113, Safari ab 26, Firefox ab 141 unter Windows. Vorher auf
navigator.gpuprüfen.