wgpu_types/error.rs
1//! Shared types for WebGPU errors. See also:
2//! <https://gpuweb.github.io/gpuweb/#errors-and-debugging>
3
4use alloc::boxed::Box;
5use alloc::string::String;
6use core::{error, fmt};
7
8/// A classification of WebGPU error for implementers of the WebGPU API to use in their own error
9/// layer(s).
10///
11/// Strongly correlates to the [`GPUError`] and [`GPUErrorFilter`] types in the WebGPU API, with an
12/// additional [`Self::DeviceLost`] variant.
13///
14/// [`GPUError`]: https://gpuweb.github.io/gpuweb/#gpuerror
15/// [`GPUErrorFilter`]: https://gpuweb.github.io/gpuweb/#enumdef-gpuerrorfilter
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
18pub enum ErrorType {
19 /// A [`GPUInternalError`].
20 ///
21 /// [`GPUInternalError`]: https://gpuweb.github.io/gpuweb/#gpuinternalerror
22 Internal,
23 /// A [`GPUOutOfMemoryError`].
24 ///
25 /// [`GPUOutOfMemoryError`]: https://gpuweb.github.io/gpuweb/#gpuoutofmemoryerror
26 OutOfMemory,
27 /// A [`GPUValidationError`].
28 ///
29 /// [`GPUValidationError`]: https://gpuweb.github.io/gpuweb/#gpuvalidationerror
30 Validation,
31 /// Indicates that device loss occurred. In JavaScript, this means the [`GPUDevice.lost`]
32 /// property should be `resolve`d.
33 ///
34 /// [`GPUDevice.lost`]: https://www.w3.org/TR/webgpu/#dom-gpudevice-lost
35 DeviceLost,
36}
37
38/// A trait for querying the [`ErrorType`] classification of an error.
39///
40/// This is intended to be used as a convenience by implementations of WebGPU to classify errors
41/// returned by [`wgpu_core`](crate).
42pub trait WebGpuError: error::Error + 'static {
43 /// Determine the classification of this error as a WebGPU [`ErrorType`].
44 fn webgpu_error_type(&self) -> ErrorType;
45}
46
47/// The callback of [`uncaptured_error`](https://gpuweb.github.io/gpuweb/#eventdef-gpudevice-uncapturederror)
48///
49/// It must be a function with this signature.
50pub trait UncapturedErrorHandler: Fn(Error) + Send + Sync + 'static {}
51impl<T> UncapturedErrorHandler for T where T: Fn(Error) + Send + Sync + 'static {}
52
53/// Kinds of [`Error`]s a [`push_error_scope`](https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope) may be configured to catch.
54///
55/// Corresponds to the [`GPUErrorFilter`] type in the WebGPU API.
56///
57/// [`GPUErrorFilter`]: https://gpuweb.github.io/gpuweb/#enumdef-gpuerrorfilter
58#[repr(C)]
59#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
60#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
61pub enum ErrorFilter {
62 /// Catch only out-of-memory errors.
63 OutOfMemory,
64 /// Catch only validation errors.
65 Validation,
66 /// Catch only internal errors.
67 Internal,
68}
69static_assertions::assert_impl_all!(ErrorFilter: Send, Sync);
70
71/// Lower level source of the error.
72///
73/// `Send + Sync` varies depending on configuration.
74#[cfg(any(
75 not(target_family = "wasm"),
76 all(
77 feature = "fragile-send-sync-non-atomic-wasm",
78 not(target_feature = "atomics")
79 )
80))]
81#[cfg_attr(docsrs, doc(cfg(all())))]
82pub type ErrorSource = Box<dyn error::Error + Send + Sync + 'static>;
83/// Lower level source of the error.
84///
85/// `Send + Sync` varies depending on configuration.
86#[cfg(not(any(
87 not(target_family = "wasm"),
88 all(
89 feature = "fragile-send-sync-non-atomic-wasm",
90 not(target_feature = "atomics")
91 )
92)))]
93#[cfg_attr(docsrs, doc(cfg(all())))]
94pub type ErrorSource = Box<dyn error::Error + 'static>;
95
96/// Errors resulting from usage of GPU APIs.
97#[derive(Debug)]
98pub enum Error {
99 /// Out of memory.
100 OutOfMemory {
101 /// Lower level source of the error.
102 source: ErrorSource,
103 },
104 /// Validation error, signifying a bug in code or data provided to `wgpu`.
105 Validation {
106 /// Lower level source of the error.
107 source: ErrorSource,
108 /// Description of the validation error.
109 description: String,
110 },
111 /// Internal error. Used for signalling any failures not explicitly expected by WebGPU.
112 ///
113 /// These could be due to internal implementation or system limits being reached.
114 Internal {
115 /// Lower level source of the error.
116 source: ErrorSource,
117 /// Description of the internal GPU error.
118 description: String,
119 },
120}
121
122impl error::Error for Error {
123 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
124 match self {
125 Error::OutOfMemory { source } => Some(source.as_ref()),
126 Error::Validation { source, .. } => Some(source.as_ref()),
127 Error::Internal { source, .. } => Some(source.as_ref()),
128 }
129 }
130}
131
132impl fmt::Display for Error {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 match self {
135 Error::OutOfMemory { .. } => f.write_str("Out of Memory"),
136 Error::Validation { description, .. } => f.write_str(description),
137 Error::Internal { description, .. } => f.write_str(description),
138 }
139 }
140}
141
142impl WebGpuError for Error {
143 fn webgpu_error_type(&self) -> ErrorType {
144 match self {
145 Error::OutOfMemory { .. } => ErrorType::OutOfMemory,
146 Error::Validation { .. } => ErrorType::Validation,
147 Error::Internal { .. } => ErrorType::Internal,
148 }
149 }
150}