1use oxicuda_backend::BackendError;
4
5#[derive(Debug, thiserror::Error)]
7pub enum WebGpuError {
8 #[error("no WebGPU adapter found")]
10 NoAdapter,
11
12 #[error("device request failed: {0}")]
14 DeviceRequest(String),
15
16 #[error("out of device memory")]
18 OutOfMemory,
19
20 #[error("WGSL shader compilation failed: {0}")]
22 ShaderCompilation(String),
23
24 #[error("pipeline creation failed: {0}")]
26 PipelineCreation(String),
27
28 #[error("not initialized")]
30 NotInitialized,
31
32 #[error("unsupported operation: {0}")]
34 Unsupported(String),
35
36 #[error("invalid argument: {0}")]
38 InvalidArgument(String),
39
40 #[error("buffer mapping failed: {0}")]
42 BufferMapping(String),
43
44 #[error("adapter timeout")]
46 Timeout,
47
48 #[error("uncaptured wgpu error: {0}")]
54 UncapturedError(String),
55
56 #[error("device lost: {0}")]
61 DeviceLost(String),
62}
63
64pub type WebGpuResult<T> = Result<T, WebGpuError>;
66
67impl From<WebGpuError> for BackendError {
68 fn from(e: WebGpuError) -> Self {
69 match e {
70 WebGpuError::NoAdapter => BackendError::DeviceError("no WebGPU adapter found".into()),
71 WebGpuError::DeviceRequest(msg) => {
72 BackendError::DeviceError(format!("device request failed: {msg}"))
73 }
74 WebGpuError::OutOfMemory => BackendError::OutOfMemory,
75 WebGpuError::ShaderCompilation(msg) => {
76 BackendError::DeviceError(format!("WGSL shader compilation failed: {msg}"))
77 }
78 WebGpuError::PipelineCreation(msg) => {
79 BackendError::DeviceError(format!("pipeline creation failed: {msg}"))
80 }
81 WebGpuError::NotInitialized => BackendError::NotInitialized,
82 WebGpuError::Unsupported(msg) => BackendError::Unsupported(msg),
83 WebGpuError::InvalidArgument(msg) => BackendError::InvalidArgument(msg),
84 WebGpuError::BufferMapping(msg) => {
85 BackendError::DeviceError(format!("buffer mapping failed: {msg}"))
86 }
87 WebGpuError::Timeout => BackendError::DeviceError("adapter timeout".into()),
88 WebGpuError::UncapturedError(msg) => {
89 BackendError::DeviceError(format!("uncaptured wgpu error: {msg}"))
90 }
91 WebGpuError::DeviceLost(msg) => {
92 BackendError::DeviceError(format!("device lost: {msg}"))
93 }
94 }
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn webgpu_error_display() {
104 assert_eq!(
105 WebGpuError::NoAdapter.to_string(),
106 "no WebGPU adapter found"
107 );
108 assert_eq!(
109 WebGpuError::DeviceRequest("oops".into()).to_string(),
110 "device request failed: oops"
111 );
112 assert_eq!(WebGpuError::OutOfMemory.to_string(), "out of device memory");
113 assert_eq!(
114 WebGpuError::ShaderCompilation("syntax error".into()).to_string(),
115 "WGSL shader compilation failed: syntax error"
116 );
117 assert_eq!(
118 WebGpuError::PipelineCreation("invalid layout".into()).to_string(),
119 "pipeline creation failed: invalid layout"
120 );
121 assert_eq!(WebGpuError::NotInitialized.to_string(), "not initialized");
122 assert_eq!(
123 WebGpuError::Unsupported("foo".into()).to_string(),
124 "unsupported operation: foo"
125 );
126 assert_eq!(
127 WebGpuError::InvalidArgument("bad arg".into()).to_string(),
128 "invalid argument: bad arg"
129 );
130 assert_eq!(
131 WebGpuError::BufferMapping("lock poisoned".into()).to_string(),
132 "buffer mapping failed: lock poisoned"
133 );
134 assert_eq!(WebGpuError::Timeout.to_string(), "adapter timeout");
135 assert_eq!(
136 WebGpuError::UncapturedError("oom".into()).to_string(),
137 "uncaptured wgpu error: oom"
138 );
139 assert_eq!(
140 WebGpuError::DeviceLost("reset".into()).to_string(),
141 "device lost: reset"
142 );
143 }
144
145 #[test]
146 fn webgpu_error_from_backend_error() {
147 let e = BackendError::from(WebGpuError::OutOfMemory);
149 assert_eq!(e, BackendError::OutOfMemory);
150
151 let e = BackendError::from(WebGpuError::NotInitialized);
152 assert_eq!(e, BackendError::NotInitialized);
153
154 let e = BackendError::from(WebGpuError::Unsupported("bar".into()));
155 assert_eq!(e, BackendError::Unsupported("bar".into()));
156
157 let e = BackendError::from(WebGpuError::InvalidArgument("baz".into()));
158 assert_eq!(e, BackendError::InvalidArgument("baz".into()));
159
160 let e = BackendError::from(WebGpuError::NoAdapter);
161 assert!(matches!(e, BackendError::DeviceError(_)));
162
163 let e = BackendError::from(WebGpuError::DeviceRequest("x".into()));
164 assert!(matches!(e, BackendError::DeviceError(_)));
165
166 let e = BackendError::from(WebGpuError::BufferMapping("m".into()));
167 assert!(matches!(e, BackendError::DeviceError(_)));
168
169 let e = BackendError::from(WebGpuError::Timeout);
170 assert!(matches!(e, BackendError::DeviceError(_)));
171
172 let e = BackendError::from(WebGpuError::UncapturedError("oom".into()));
173 assert!(matches!(e, BackendError::DeviceError(_)));
174
175 let e = BackendError::from(WebGpuError::DeviceLost("reset".into()));
176 assert!(matches!(e, BackendError::DeviceError(_)));
177 }
178}