rutabaga_gfx: add better error reporting
Both RutabagaError::SpecViolation and RutabagaError::Unsupported
are used as catch-alls for errors that don't fit any one
particular place.
With this change, RutabagaError::Unsupported means that a particular
function is not implemented.
RutabagaError::SpecViolation(..) now provides free-form debug
reporting for one-off errors. However, it is recommended to create a
new RutabagaError variant if two instances of the same spec violation
are noticed. Many new variants are added in CL in observance of this
recommendation.
In addition, we may create a CrossDomainError and RutabagaGrallocError
one day. Currently, it doesn't make sense to do so at the moment.
But prefix the new variants accordingly if the need arises.
BUG=b:173630595
TEST=compile and run
Change-Id: Ie610c77445f4406b40bb40f00bcabb8e65c8e02d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3203231
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Jason Macnak <natsu@google.com>
Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org>
Reviewed-by: Dennis Kempin <denniskempin@google.com>
diff --git a/rutabaga_gfx/src/cross_domain/cross_domain.rs b/rutabaga_gfx/src/cross_domain/cross_domain.rs
index 4369e32..c4d8c25 100644
--- a/rutabaga_gfx/src/cross_domain/cross_domain.rs
+++ b/rutabaga_gfx/src/cross_domain/cross_domain.rs
@@ -146,10 +146,9 @@
Ok(())
}
_ => {
- // Expect to receive the write end of a Wayland pipe only.
*descriptor_type = match FileFlags::from_file(descriptor) {
Ok(FileFlags::Write) => CROSS_DOMAIN_ID_TYPE_WRITE_PIPE,
- _ => return Err(RutabagaError::SpecViolation),
+ _ => return Err(RutabagaError::InvalidCrossDomainItemType),
};
Ok(())
}
@@ -272,7 +271,7 @@
) -> RutabagaResult<usize> {
self.connection
.as_ref()
- .ok_or(RutabagaError::SpecViolation)
+ .ok_or(RutabagaError::InvalidCrossDomainChannel)
.and_then(|conn| Ok(conn.send_with_fds(opaque_data, descriptors)?))
}
@@ -294,7 +293,7 @@
Ok((len, files))
} else {
- Err(RutabagaError::SpecViolation)
+ Err(RutabagaError::InvalidCrossDomainChannel)
}
}
}
@@ -366,7 +365,7 @@
&self.item_state,
CrossDomainItem::WaylandWritePipe(file),
),
- _ => return Err(RutabagaError::SpecViolation),
+ _ => return Err(RutabagaError::InvalidCrossDomainItemType),
};
}
@@ -402,7 +401,7 @@
let item = items
.table
.get_mut(&pipe_id)
- .ok_or(RutabagaError::SpecViolation)?;
+ .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
match item {
CrossDomainItem::WaylandReadPipe(ref mut file) => {
@@ -417,7 +416,7 @@
self.wait_ctx.delete(file)?;
}
}
- _ => return Err(RutabagaError::SpecViolation),
+ _ => return Err(RutabagaError::InvalidCrossDomainItemType),
}
if event.is_hungup && bytes_read == 0 {
@@ -459,13 +458,13 @@
let item = items
.table
.get(&read_pipe_id)
- .ok_or(RutabagaError::SpecViolation)?;
+ .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
match item {
CrossDomainItem::WaylandReadPipe(file) => self
.wait_ctx
.add(file, CrossDomainToken::WaylandReadPipe(read_pipe_id))?,
- _ => return Err(RutabagaError::SpecViolation),
+ _ => return Err(RutabagaError::InvalidCrossDomainItemType),
}
}
}
@@ -504,11 +503,14 @@
// Zero means no requested channel.
if cmd_init.channel_type != 0 {
- let channels = self.channels.take().ok_or(RutabagaError::SpecViolation)?;
+ let channels = self
+ .channels
+ .take()
+ .ok_or(RutabagaError::InvalidCrossDomainChannel)?;
let base_channel = &channels
.iter()
.find(|channel| channel.channel_type == cmd_init.channel_type)
- .ok_or(RutabagaError::SpecViolation)?
+ .ok_or(RutabagaError::InvalidCrossDomainChannel)?
.base_channel;
let connection = UnixStream::connect(base_channel)?;
@@ -591,7 +593,7 @@
state.write_to_ring(RingWrite::Write(response, None))?;
Ok(())
} else {
- Err(RutabagaError::SpecViolation)
+ Err(RutabagaError::InvalidCrossDomainState)
}
}
@@ -608,7 +610,9 @@
let num_identifiers = cmd_send.num_identifiers.try_into()?;
if num_identifiers > CROSS_DOMAIN_MAX_IDENTIFIERS {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::SpecViolation(
+ "max cross domain identifiers exceeded",
+ ));
}
let iter = cmd_send
@@ -629,13 +633,13 @@
if let Some(ref handle) = context_resource.handle {
*descriptor = handle.os_handle.as_raw_descriptor();
} else {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidRutabagaHandle);
}
} else if *identifier_type == CROSS_DOMAIN_ID_TYPE_READ_PIPE {
- // In practice, just 1 write or read pipe per send is observed. If we encounter
+ // In practice, just 1 pipe pair per send is observed. If we encounter
// more, this can be changed later.
if write_pipe_opt.is_some() {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::SpecViolation("expected just one pipe pair"));
}
let (read_pipe, write_pipe) = pipe(true)?;
@@ -651,7 +655,7 @@
// because of the way Sommelier copy + paste works. If the Sommelier sequence of events
// changes, it's always possible to wait for the host response.
if read_pipe_id != *identifier {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidCrossDomainItemId);
}
// The write pipe needs to be dropped after the send_msg(..) call is complete, so the read pipe
@@ -660,7 +664,7 @@
read_pipe_id_opt = Some(read_pipe_id);
} else {
// Don't know how to handle anything else yet.
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidCrossDomainItemType);
}
}
@@ -672,7 +676,7 @@
resample_evt.write(1)?;
}
} else {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidCrossDomainState);
}
Ok(())
@@ -691,7 +695,7 @@
let item = items
.table
.remove(&cmd_write.identifier)
- .ok_or(RutabagaError::SpecViolation)?;
+ .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
let len: usize = cmd_write.opaque_data_size.try_into()?;
match item {
@@ -709,7 +713,7 @@
Ok(())
}
- _ => Err(RutabagaError::SpecViolation),
+ _ => Err(RutabagaError::InvalidCrossDomainItemType),
}
}
}
@@ -755,12 +759,12 @@
let item = items
.table
.get(&item_id)
- .ok_or(RutabagaError::SpecViolation)?;
+ .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
match item {
CrossDomainItem::ImageRequirements(reqs) => {
if reqs.size != resource_create_blob.size {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::SpecViolation("blob size mismatch"));
}
// Strictly speaking, it's against the virtio-gpu spec to allocate memory in the context
@@ -794,7 +798,7 @@
backing_iovecs: None,
})
}
- _ => Err(RutabagaError::SpecViolation),
+ _ => Err(RutabagaError::InvalidCrossDomainItemType),
}
} else {
let item = self
@@ -802,7 +806,7 @@
.lock()
.table
.remove(&item_id)
- .ok_or(RutabagaError::SpecViolation)?;
+ .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
match item {
CrossDomainItem::WaylandKeymap(descriptor) => {
@@ -824,7 +828,7 @@
backing_iovecs: None,
})
}
- _ => Err(RutabagaError::SpecViolation),
+ _ => Err(RutabagaError::InvalidCrossDomainItemType),
}
}
}
@@ -870,7 +874,7 @@
self.write(&cmd_write, opaque_data)?;
}
- _ => return Err(RutabagaError::Unsupported),
+ _ => return Err(RutabagaError::SpecViolation("invalid cross domain command")),
}
offset += hdr.cmd_size as usize;
@@ -911,7 +915,7 @@
state.add_job(CrossDomainJob::HandleFence(fence));
}
}
- _ => return Err(RutabagaError::SpecViolation),
+ _ => return Err(RutabagaError::SpecViolation("unexpected ring type")),
}
Ok(())
@@ -954,7 +958,9 @@
if resource_create_blob.blob_mem != RUTABAGA_BLOB_MEM_GUEST
&& resource_create_blob.blob_flags != RUTABAGA_BLOB_FLAG_USE_MAPPABLE
{
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::SpecViolation(
+ "expected only guest memory blobs",
+ ));
}
Ok(RutabagaResource {
diff --git a/rutabaga_gfx/src/rutabaga_2d.rs b/rutabaga_gfx/src/rutabaga_2d.rs
index acfbc82..bf5ee91 100644
--- a/rutabaga_gfx/src/rutabaga_2d.rs
+++ b/rutabaga_gfx/src/rutabaga_2d.rs
@@ -192,12 +192,15 @@
return Ok(());
}
- let mut info_2d = resource.info_2d.take().ok_or(RutabagaError::Unsupported)?;
+ let mut info_2d = resource
+ .info_2d
+ .take()
+ .ok_or(RutabagaError::Invalid2DInfo)?;
let iovecs = resource
.backing_iovecs
.take()
- .ok_or(RutabagaError::Unsupported)?;
+ .ok_or(RutabagaError::InvalidIovec)?;
// All offical virtio_gpu formats are 4 bytes per pixel.
let resource_bpp = 4;
@@ -241,7 +244,10 @@
transfer: Transfer3D,
buf: Option<VolatileSlice>,
) -> RutabagaResult<()> {
- let mut info_2d = resource.info_2d.take().ok_or(RutabagaError::Unsupported)?;
+ let mut info_2d = resource
+ .info_2d
+ .take()
+ .ok_or(RutabagaError::Invalid2DInfo)?;
// All offical virtio_gpu formats are 4 bytes per pixel.
let resource_bpp = 4;
@@ -249,7 +255,9 @@
let src_offset = 0;
let dst_offset = 0;
- let dst_slice = buf.ok_or(RutabagaError::Unsupported)?;
+ let dst_slice = buf.ok_or(RutabagaError::SpecViolation(
+ "need a destination slice for transfer read",
+ ))?;
transfer_2d(
info_2d.width,
diff --git a/rutabaga_gfx/src/rutabaga_core.rs b/rutabaga_gfx/src/rutabaga_core.rs
index 46175f0..f5cd56d 100644
--- a/rutabaga_gfx/src/rutabaga_core.rs
+++ b/rutabaga_gfx/src/rutabaga_core.rs
@@ -507,7 +507,9 @@
.get(&resource_id)
.ok_or(RutabagaError::InvalidResourceId)?;
- resource.map_info.ok_or(RutabagaError::SpecViolation)
+ resource
+ .map_info
+ .ok_or(RutabagaError::SpecViolation("no map info available"))
}
/// Returns the `vulkan_info` of the blob resource, which consists of the physical device
@@ -518,7 +520,7 @@
.get(&resource_id)
.ok_or(RutabagaError::InvalidResourceId)?;
- resource.vulkan_info.ok_or(RutabagaError::Unsupported)
+ resource.vulkan_info.ok_or(RutabagaError::InvalidVulkanInfo)
}
/// Returns the 3D info associated with the resource, if any.
@@ -528,7 +530,9 @@
.get(&resource_id)
.ok_or(RutabagaError::InvalidResourceId)?;
- resource.info_3d.ok_or(RutabagaError::Unsupported)
+ resource
+ .info_3d
+ .ok_or(RutabagaError::SpecViolation("no 3d info available"))
}
/// Exports a blob resource. See virtio-gpu spec for blob flag use flags.
@@ -552,10 +556,11 @@
}
(Some(handle), false) => {
// Exactly one strong reference in this case.
- let hnd = Arc::try_unwrap(handle).map_err(|_| RutabagaError::SpecViolation)?;
+ let hnd =
+ Arc::try_unwrap(handle).map_err(|_| RutabagaError::InvalidRutabagaHandle)?;
Ok(hnd)
}
- _ => Err(RutabagaError::Unsupported),
+ _ => Err(RutabagaError::InvalidRutabagaHandle),
}
}
diff --git a/rutabaga_gfx/src/rutabaga_gralloc/formats.rs b/rutabaga_gfx/src/rutabaga_gralloc/formats.rs
index 8803b5b..6dd0ac6 100644
--- a/rutabaga_gfx/src/rutabaga_gralloc/formats.rs
+++ b/rutabaga_gfx/src/rutabaga_gralloc/formats.rs
@@ -136,7 +136,7 @@
DRM_FORMAT_ABGR16161616F => Ok(PACKED_8BPP),
DRM_FORMAT_NV12 => Ok(BIPLANAR_YUV420),
DRM_FORMAT_YVU420 => Ok(TRIPLANAR_YUV420),
- _ => Err(RutabagaError::Unsupported),
+ _ => Err(RutabagaError::InvalidGrallocDrmFormat),
}
}
@@ -158,7 +158,7 @@
DRM_FORMAT_ABGR16161616F => Ok(VulkanFormat::R16G16B16A16Sfloat),
DRM_FORMAT_NV12 => Ok(VulkanFormat::G8B8R8_2PLANE420Unorm),
DRM_FORMAT_YVU420 => Ok(VulkanFormat::G8B8R8_3PLANE420Unorm),
- _ => Err(RutabagaError::Unsupported),
+ _ => Err(RutabagaError::InvalidGrallocDrmFormat),
}
}
@@ -180,15 +180,15 @@
DRM_FORMAT_NV12 => match plane {
0 => Ok(VulkanImageAspect::Plane0),
1 => Ok(VulkanImageAspect::Plane1),
- _ => Err(RutabagaError::Unsupported),
+ _ => Err(RutabagaError::InvalidGrallocNumberOfPlanes),
},
DRM_FORMAT_YVU420 => match plane {
0 => Ok(VulkanImageAspect::Plane0),
1 => Ok(VulkanImageAspect::Plane1),
2 => Ok(VulkanImageAspect::Plane2),
- _ => Err(RutabagaError::Unsupported),
+ _ => Err(RutabagaError::InvalidGrallocNumberOfPlanes),
},
- _ => Err(RutabagaError::Unsupported),
+ _ => Err(RutabagaError::InvalidGrallocDrmFormat),
}
}
}
diff --git a/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs b/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs
index 9b3f25f..d950c4f 100644
--- a/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs
+++ b/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs
@@ -303,7 +303,7 @@
let gralloc = self
.grallocs
.get_mut(&backend)
- .ok_or(RutabagaError::Unsupported)?;
+ .ok_or(RutabagaError::InvalidGrallocBackend)?;
let mut reqs = gralloc.get_image_memory_requirements(info)?;
reqs.size = round_up_to_page_size(reqs.size as usize) as u64;
@@ -320,7 +320,7 @@
let gralloc = self
.grallocs
.get_mut(&backend)
- .ok_or(RutabagaError::Unsupported)?;
+ .ok_or(RutabagaError::InvalidGrallocBackend)?;
gralloc.allocate_memory(reqs)
}
@@ -336,7 +336,7 @@
let gralloc = self
.grallocs
.get_mut(&GrallocBackend::Vulkano)
- .ok_or(RutabagaError::Unsupported)?;
+ .ok_or(RutabagaError::InvalidGrallocBackend)?;
gralloc.import_and_map(handle, vulkan_info, size)
}
diff --git a/rutabaga_gfx/src/rutabaga_gralloc/minigbm.rs b/rutabaga_gfx/src/rutabaga_gralloc/minigbm.rs
index e4d4b05..c86e7cf 100644
--- a/rutabaga_gfx/src/rutabaga_gralloc/minigbm.rs
+++ b/rutabaga_gfx/src/rutabaga_gralloc/minigbm.rs
@@ -140,7 +140,7 @@
|| gbm_buffer.height() != reqs.info.height
|| gbm_buffer.format() != reqs.info.drm_format
{
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidGrallocDimensions);
}
let dmabuf = gbm_buffer.export()?.into();
diff --git a/rutabaga_gfx/src/rutabaga_gralloc/rendernode.rs b/rutabaga_gfx/src/rutabaga_gralloc/rendernode.rs
index 9972ab5..d7fe1d3 100644
--- a/rutabaga_gfx/src/rutabaga_gralloc/rendernode.rs
+++ b/rutabaga_gfx/src/rutabaga_gralloc/rendernode.rs
@@ -105,5 +105,5 @@
}
}
- Err(RutabagaError::Unsupported)
+ Err(RutabagaError::SpecViolation("no DRM rendernode opened"))
}
diff --git a/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs b/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs
index b0912db..00a4327 100644
--- a/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs
+++ b/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs
@@ -82,7 +82,9 @@
// We take the first queue family that supports graphics.
q.supports_graphics()
})
- .ok_or(RutabagaError::Unsupported)?;
+ .ok_or(RutabagaError::SpecViolation(
+ "need graphics queue family to proceed",
+ ))?;
let supported_extensions = DeviceExtensions::supported_by_device(physical);
@@ -135,11 +137,11 @@
let device = if self.has_integrated_gpu {
self.devices
.get(&PhysicalDeviceType::IntegratedGpu)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::InvalidGrallocGpuType)?
} else {
self.devices
.get(&PhysicalDeviceType::DiscreteGpu)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::InvalidGrallocGpuType)?
};
let usage = match info.flags.uses_rendering() {
@@ -155,12 +157,12 @@
// Reasonable bounds on image width.
if info.width == 0 || info.width > 4096 {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidGrallocDimensions);
}
// Reasonable bounds on image height.
if info.height == 0 || info.height > 4096 {
- return Err(RutabagaError::SpecViolation);
+ return Err(RutabagaError::InvalidGrallocDimensions);
}
let vulkan_format = info.drm_format.vulkan_format()?;
@@ -217,11 +219,11 @@
let device = if self.has_integrated_gpu {
self.devices
.get(&PhysicalDeviceType::IntegratedGpu)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::InvalidGrallocGpuType)?
} else {
self.devices
.get(&PhysicalDeviceType::DiscreteGpu)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::InvalidGrallocGpuType)?
};
let planar_layout = info.drm_format.planar_layout()?;
@@ -276,7 +278,9 @@
.chain(second_loop)
.filter(|&(t, _)| (memory_requirements.memory_type_bits & (1 << t.id())) != 0)
.find(|&(t, rq)| filter(t) == rq)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::SpecViolation(
+ "unable to find required memory type",
+ ))?
.0
};
@@ -302,22 +306,22 @@
fn allocate_memory(&mut self, reqs: ImageMemoryRequirements) -> RutabagaResult<RutabagaHandle> {
let (unsafe_image, memory_requirements) = unsafe { self.create_image(reqs.info)? };
- let vulkan_info = reqs.vulkan_info.ok_or(RutabagaError::SpecViolation)?;
+ let vulkan_info = reqs.vulkan_info.ok_or(RutabagaError::InvalidVulkanInfo)?;
let device = if self.has_integrated_gpu {
self.devices
.get(&PhysicalDeviceType::IntegratedGpu)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::InvalidGrallocGpuType)?
} else {
self.devices
.get(&PhysicalDeviceType::DiscreteGpu)
- .ok_or(RutabagaError::Unsupported)?
+ .ok_or(RutabagaError::InvalidGrallocGpuType)?
};
let memory_type = device
.physical_device()
.memory_type_by_id(vulkan_info.memory_idx)
- .ok_or(RutabagaError::SpecViolation)?;
+ .ok_or(RutabagaError::InvalidVulkanInfo)?;
let (handle_type, rutabaga_type) =
match device.enabled_extensions().ext_external_memory_dma_buf {
@@ -374,7 +378,7 @@
.find(|device| {
device.physical_device().index() as u32 == vulkan_info.physical_device_idx
})
- .ok_or(RutabagaError::Unsupported)?;
+ .ok_or(RutabagaError::InvalidVulkanInfo)?;
let handle_type = match handle.handle_type {
RUTABAGA_MEM_HANDLE_TYPE_DMABUF => ExternalMemoryHandleType {
@@ -385,7 +389,7 @@
opaque_fd: true,
..ExternalMemoryHandleType::none()
},
- _ => return Err(RutabagaError::Unsupported),
+ _ => return Err(RutabagaError::InvalidRutabagaHandle),
};
let device_memory = DeviceMemoryBuilder::new(device.clone(), vulkan_info.memory_idx, size)
diff --git a/rutabaga_gfx/src/rutabaga_utils.rs b/rutabaga_gfx/src/rutabaga_utils.rs
index 9e7aebe..685d3b1 100644
--- a/rutabaga_gfx/src/rutabaga_utils.rs
+++ b/rutabaga_gfx/src/rutabaga_utils.rs
@@ -145,9 +145,9 @@
/// An internal Rutabaga component error was returned.
#[error("rutabaga component failed with error {0}")]
ComponentError(i32),
- /// The Rutabaga component failed to export a RutabagaHandle.
- #[error("failed to export Rutabaga handle")]
- ExportedRutabagaHandle,
+ /// Invalid 2D info
+ #[error("invalid 2D info")]
+ Invalid2DInfo,
/// Invalid Capset
#[error("invalid capset")]
InvalidCapset,
@@ -160,6 +160,33 @@
/// Invalid Context ID
#[error("invalid context id")]
InvalidContextId,
+ /// Invalid cross domain channel
+ #[error("invalid cross domain channel")]
+ InvalidCrossDomainChannel,
+ /// Invalid cross domain item ID
+ #[error("invalid cross domain item id")]
+ InvalidCrossDomainItemId,
+ /// Invalid cross domain item type
+ #[error("invalid cross domain item type")]
+ InvalidCrossDomainItemType,
+ /// Invalid cross domain state
+ #[error("invalid cross domain state")]
+ InvalidCrossDomainState,
+ /// Invalid gralloc backend.
+ #[error("invalid gralloc backend")]
+ InvalidGrallocBackend,
+ /// Invalid gralloc dimensions.
+ #[error("invalid gralloc dimensions")]
+ InvalidGrallocDimensions,
+ /// Invalid gralloc DRM format.
+ #[error("invalid gralloc DRM format")]
+ InvalidGrallocDrmFormat,
+ /// Invalid GPU type.
+ #[error("invalid GPU type for gralloc")]
+ InvalidGrallocGpuType,
+ /// Invalid number of YUV planes.
+ #[error("invalid number of YUV planes")]
+ InvalidGrallocNumberOfPlanes,
/// The indicated region of guest memory is invalid.
#[error("an iovec is outside of guest memory's range")]
InvalidIovec,
@@ -169,6 +196,12 @@
/// Indicates an error in the RutabagaBuilder.
#[error("invalid rutabaga build parameters")]
InvalidRutabagaBuild,
+ /// An error with the RutabagaHandle
+ #[error("invalid rutabaga handle")]
+ InvalidRutabagaHandle,
+ /// Invalid Vulkan info
+ #[error("invalid vulkan info")]
+ InvalidVulkanInfo,
/// An input/output error occured.
#[error("an input/output error occur: {0}")]
IoError(IoError),
@@ -176,13 +209,13 @@
#[error("The mapping failed for the following reason: {0}")]
MappingFailed(ExternalMappingError),
/// Violation of the Rutabaga spec occured.
- #[error("violation of the rutabaga spec")]
- SpecViolation,
+ #[error("violation of the rutabaga spec: {0}")]
+ SpecViolation(&'static str),
/// An attempted integer conversion failed.
#[error("int conversion failed: {0}")]
TryFromIntError(TryFromIntError),
/// The command is unsupported.
- #[error("feature or function unsupported")]
+ #[error("the requested function is not implemented")]
Unsupported,
/// Utf8 error.
#[error("an utf8 error occured: {0}")]
@@ -484,7 +517,7 @@
let clone = self
.os_handle
.try_clone()
- .map_err(|_| RutabagaError::Unsupported)?;
+ .map_err(|_| RutabagaError::InvalidRutabagaHandle)?;
Ok(RutabagaHandle {
os_handle: clone,
handle_type: self.handle_type,