Signatur
Beschreibung
GPUPipelineError ist der Fehlertyp, mit dem die Promises von GPUDevice.createRenderPipelineAsync() und GPUDevice.createComputePipelineAsync() abgelehnt werden, wenn die Pipeline nicht erzeugt werden kann. Die Schnittstelle erbt von DOMException. Deshalb sind neben der eigenen Eigenschaft reason auch name (immer "GPUPipelineError") und message verfügbar.
Die Eigenschaft reason gibt an, warum die Pipeline gescheitert ist:
"validation": Der Pipeline-Deskriptor ist ungültig, zum Beispiel wegen eines falschen Einstiegspunkts, eines Shader-Kompilierfehlers, eines unpassenden Layouts oder eines nicht unterstützten Formats."internal": Die Erzeugung ist aus einem Grund fehlgeschlagen, den die Validierung nicht erkennen kann, etwa wegen einer Einschränkung des Treibers oder der Hardware. Das sind oft Probleme, die von der Implementierung abhängen.
Die synchronen Varianten createRenderPipeline() und createComputePipeline() werfen keinen GPUPipelineError. Bei ihnen landet ein Fehler als GPUValidationError oder GPUInternalError im Fehlerbereich (pushErrorScope()/popErrorScope()) oder im Ereignis uncapturederror. Bei den asynchronen Methoden fängt man den Fehler dagegen direkt mit try/catch ab.
Den Konstruktor new GPUPipelineError(message, options) ruft man selten selbst auf. Nützlich ist er vor allem in Tests, Mocks oder eigenen Abstraktionsschichten, die das Verhalten des Browsers nachbilden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $message | string | "" | Konstruktor-Parameter: menschenlesbare Fehlermeldung, die über message abrufbar ist. |
| $options Pflicht | { reason: "validation" | "internal" } | Konstruktor-Parameter: Objekt mit der Pflicht-Eigenschaft reason, die den Fehlergrund festlegt. |
Rückgabewert
reason ("validation" oder "internal") sowie den von DOMException geerbten Eigenschaften name und message.Beispiele
Fehler bei createRenderPipelineAsync() abfangen
const adapter = await navigator.gpu?.requestAdapter();
if (!adapter) throw new Error('WebGPU wird nicht unterstützt');
const device = await adapter.requestDevice();
const shaderModule = device.createShaderModule({
code: `
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
return vec4f(0.0, 0.0, 0.0, 1.0);
}
@fragment fn fs() -> @location(0) vec4f {
return vec4f(1.0, 0.0, 0.0, 1.0);
}
`
});
try {
const pipeline = await device.createRenderPipelineAsync({
layout: 'auto',
vertex: { module: shaderModule, entryPoint: 'vs' },
// Absichtlich falscher Einstiegspunkt -> Validierungsfehler
fragment: {
module: shaderModule,
entryPoint: 'gibtEsNicht',
targets: [{ format: navigator.gpu.getPreferredCanvasFormat() }]
}
});
} catch (err) {
if (err instanceof GPUPipelineError) {
console.log(err.name, err.reason);
console.log(err.message);
} else {
throw err;
}
}
Compute-Pipeline mit Rückfall auf eine einfachere Shader-Variante
const createPipelineWithFallback = async (device, sources) => {
for (const code of sources) {
try {
return await device.createComputePipelineAsync({
layout: 'auto',
compute: { module: device.createShaderModule({ code }), entryPoint: 'main' }
});
} catch (err) {
if (!(err instanceof GPUPipelineError)) throw err;
// Bei 'internal' (Treiber-/Hardware-Grenzen) die nächste Variante probieren
console.warn(`Pipeline fehlgeschlagen (${err.reason}): ${err.message}`);
if (err.reason === 'validation') throw err; // Programmierfehler nicht verschleiern
}
}
throw new Error('Keine Shader-Variante konnte erzeugt werden');
};
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const pipeline = await createPipelineWithFallback(device, [
'@compute @workgroup_size(256) fn main() {}',
'@compute @workgroup_size(64) fn main() {}'
]);
console.log(pipeline instanceof GPUComputePipeline);
Instanz manuell erzeugen (z. B. für Tests)
const err = new GPUPipelineError('Shader-Kompilierung fehlgeschlagen', {
reason: 'validation'
});
console.log(err instanceof DOMException);
console.log(err.name);
console.log(err.reason);
console.log(err.message);
// Wichtig · Fallstricke
- Nur bei asynchronen Methoden:
GPUPipelineErrortritt nur bei der Ablehnung voncreateRenderPipelineAsync()undcreateComputePipelineAsync()auf. Die synchronen Methoden liefern immer ein Pipeline-Objekt zurück. Dieses ist bei einem Fehler ungültig, und der Fehler wird alsGPUValidationErroroderGPUInternalErrorgemeldet. - Nicht nur
GPUPipelineErrorerwarten: Die Promises können auch aus anderen Gründen abgelehnt werden. Deshalb imcatch-Block mitinstanceofprüfen und unbekannte Fehler weiterwerfen. - Meldungen sind nicht standardisiert: Der Text von
messageunterscheidet sich je nach Browser und Version. Programmlogik sollte sich nur aufreasonstützen und nicht den Meldungstext auswerten. - Ausführlichere Shader-Fehler: Zeilengenaue Kompilierfehler liefert
GPUShaderModule.getCompilationInfo(). - Kompatibilität: WebGPU funktioniert nur in einem sicheren Kontext (HTTPS oder localhost) und ist auch in Web Workern verfügbar. Unterstützt wird die API von Chrome/Edge ab 113 (unter Linux teils hinter einem Flag), von Firefox ab 141 (vorerst unter Windows) und von Safari ab 26. Vor der Nutzung sollte man mit
navigator.gpuprüfen, ob die API vorhanden ist.