Signatur
Beschreibung
GPUValidationError ist eine Unterklasse von GPUError und steht für einen Anwendungsfehler: Ein WebGPU-Aufruf hat die Validierungsregeln der Spezifikation verletzt. Typische Ursachen sind ungültige Deskriptoren, falsche Usage-Flags bei Puffern oder Texturen, nicht passende Bind-Group-Layouts, WGSL-Shader mit Fehlern oder Zugriffe außerhalb der gültigen Grenzen.
WebGPU arbeitet asynchron. Deshalb lösen fehlerhafte Aufrufe wie device.createBuffer() keine Ausnahme aus. Stattdessen entsteht ein intern ungültiges Objekt, und der Fehler wird gesondert gemeldet. Du kannst ihn auf zwei Wegen abfangen:
- mit Error Scopes:
device.pushErrorScope("validation")vor den Aufrufen, danachawait device.popErrorScope(). Das Promise liefert einGPUValidationErrorodernull. - über das Event
uncapturederroramGPUDevice. Es erhält alle Fehler, die kein Error Scope abgefangen hat, alsGPUUncapturedErrorEvent.
Die einzige Instanz-Eigenschaft ist message, geerbt von GPUError. Sie enthält eine lesbare Beschreibung für Menschen, deren Wortlaut vom Browser abhängt. Mit dem Konstruktor new GPUValidationError(message) kannst du Instanzen selbst erzeugen, etwa für Tests oder Polyfills. Im normalen Betrieb legt der Browser sie an.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $message Pflicht | string | Nur beim Konstruktor new GPUValidationError(message): die Fehlermeldung, die in der Eigenschaft message landet. |
Rückgabewert
message (string) enthält die Fehlerbeschreibung.Beispiele
Validierungsfehler mit einem Error Scope abfangen
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
device.pushErrorScope("validation");
// Fehler: MAP_READ darf nur zusammen mit COPY_DST verwendet werden
const buffer = device.createBuffer({
size: 256,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.VERTEX
});
const error = await device.popErrorScope();
if (error instanceof GPUValidationError) {
console.error("Validierungsfehler:", error.message);
} else {
console.log("Puffer gültig erstellt");
}
Nicht abgefangene Fehler global protokollieren
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
device.addEventListener("uncapturederror", (event) => {
const { error } = event;
if (error instanceof GPUValidationError) {
console.warn("[WebGPU-Validierung]", error.message);
} else if (error instanceof GPUOutOfMemoryError) {
console.warn("[WebGPU] Speicher erschöpft");
}
});
// Absichtlicher Fehler: Textur mit Größe 0
device.createTexture({
size: [0, 0],
format: "rgba8unorm",
usage: GPUTextureUsage.TEXTURE_BINDING
});
Shader-Modul prüfen, bevor die Pipeline gebaut wird
const createCheckedShader = async (device, code) => {
device.pushErrorScope("validation");
const module = device.createShaderModule({ code });
const error = await device.popErrorScope();
if (error) {
// Detaillierte Compiler-Meldungen abrufen
const info = await module.getCompilationInfo();
for (const msg of info.messages) {
console.error(`Zeile ${msg.lineNum}: ${msg.message}`);
}
throw new Error(`Shader ungültig: ${error.message}`);
}
return module;
};
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
await createCheckedShader(device, "@vertex fn main() -> vec4f { return 1; }");
Instanz manuell erzeugen (z. B. für Tests)
const err = new GPUValidationError("Testfehler: ungültiger Deskriptor");
console.log(err instanceof GPUError); // true
console.log(err.message);
// Wichtig · Fallstricke
- Keine Ausnahmen: Validierungsfehler werden nicht synchron geworfen. Ein
try/catchumcreateBuffer()und ähnliche Aufrufe fängt sie nicht ab. Verwende stattdessenpushErrorScope()/popErrorScope()oderuncapturederror. - Folgefehler: Ein ungültiges Objekt macht alle Objekte ungültig, die darauf aufbauen. Oft folgen einem ersten Fehler viele weitere Meldungen. Beheben solltest du immer den ersten Fehler.
- Error Scopes sind ein Stapel: Jedes
pushErrorScope()braucht ein passendespopErrorScope(). Ein Scope fängt nur den ersten Fehler seines Filtertyps ("validation","out-of-memory","internal"). - Meldungstext nicht auswerten:
messageist nicht standardisiert und kann sich je nach Browser und Version ändern. Nutze sie nur für Logging und Debugging, nicht für Programmlogik. - Performance: Häufiges
await popErrorScope()in der Render-Schleife verursacht Synchronisationsaufwand. Setze Scopes gezielt bei der Initialisierung oder beim Debuggen ein. - Kompatibilität: WebGPU gibt es nur in sicheren Kontexten und noch nicht in allen Browsern und auf allen Plattformen. Prüfe vorher, ob
navigator.gpuvorhanden ist.