misc: block: streamline #[source] and Error

This streamlines the code base to follow best practices for
error handling in Rust: Each error struct implements
std::error::Error (most due via thiserror::Error derive macro)
and sets its source accordingly.

This allows future work that nicely prints the error chains,
for example.

So far, the convention is that each error prints its
sub error as part of its Display::fmt() impl.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster
2025-05-19 09:50:05 +02:00
committed by Rob Bradford
parent a212343908
commit 01761c2596
5 changed files with 49 additions and 49 deletions
+20 -20
View File
@@ -68,9 +68,9 @@ pub const SECTOR_SIZE: u64 = 0x01 << SECTOR_SHIFT;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {
#[error("Guest gave us bad memory addresses")] #[error("Guest gave us bad memory addresses")]
GuestMemory(GuestMemoryError), GuestMemory(#[source] GuestMemoryError),
#[error("Guest gave us offsets that would have overflowed a usize")] #[error("Guest gave us offsets that would have overflowed a usize")]
CheckedOffset(GuestAddress, usize), CheckedOffset(GuestAddress, usize /* sector offset */),
#[error("Guest gave us a write only descriptor that protocol says to read from")] #[error("Guest gave us a write only descriptor that protocol says to read from")]
UnexpectedWriteOnlyDescriptor, UnexpectedWriteOnlyDescriptor,
#[error("Guest gave us a read only descriptor that protocol says to write to")] #[error("Guest gave us a read only descriptor that protocol says to write to")]
@@ -80,21 +80,21 @@ pub enum Error {
#[error("Guest gave us a descriptor that was too short to use")] #[error("Guest gave us a descriptor that was too short to use")]
DescriptorLengthTooSmall, DescriptorLengthTooSmall,
#[error("Failed to detect image type: {0}")] #[error("Failed to detect image type: {0}")]
DetectImageType(std::io::Error), DetectImageType(#[source] std::io::Error),
#[error("Failure in fixed vhd: {0}")] #[error("Failure in fixed vhd: {0}")]
FixedVhdError(std::io::Error), FixedVhdError(#[source] std::io::Error),
#[error("Getting a block's metadata fails for any reason")] #[error("Getting a block's metadata fails for any reason")]
GetFileMetadata, GetFileMetadata,
#[error("The requested operation would cause a seek beyond disk end")] #[error("The requested operation would cause a seek beyond disk end")]
InvalidOffset, InvalidOffset,
#[error("Failure in qcow: {0}")] #[error("Failure in qcow: {0}")]
QcowError(qcow::Error), QcowError(#[source] qcow::Error),
#[error("Failure in raw file: {0}")] #[error("Failure in raw file: {0}")]
RawFileError(std::io::Error), RawFileError(#[source] std::io::Error),
#[error("The requested operation does not support multiple descriptors")] #[error("The requested operation does not support multiple descriptors")]
TooManyDescriptors, TooManyDescriptors,
#[error("Failure in vhdx: {0}")] #[error("Failure in vhdx: {0}")]
VhdxError(VhdxError), VhdxError(#[source] VhdxError),
} }
fn build_device_id(disk_path: &Path) -> result::Result<String, Error> { fn build_device_id(disk_path: &Path) -> result::Result<String, Error> {
@@ -132,33 +132,33 @@ pub fn build_serial(disk_path: &Path) -> Vec<u8> {
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum ExecuteError { pub enum ExecuteError {
#[error("Bad request: {0}")] #[error("Bad request: {0}")]
BadRequest(Error), BadRequest(#[source] Error),
#[error("Failed to flush: {0}")] #[error("Failed to flush: {0}")]
Flush(io::Error), Flush(#[source] io::Error),
#[error("Failed to read: {0}")] #[error("Failed to read: {0}")]
Read(GuestMemoryError), Read(#[source] GuestMemoryError),
#[error("Failed to read_exact: {0}")] #[error("Failed to read_exact: {0}")]
ReadExact(io::Error), ReadExact(#[source] io::Error),
#[error("Failed to seek: {0}")] #[error("Failed to seek: {0}")]
Seek(io::Error), Seek(#[source] io::Error),
#[error("Failed to write: {0}")] #[error("Failed to write: {0}")]
Write(GuestMemoryError), Write(#[source] GuestMemoryError),
#[error("Failed to write_all: {0}")] #[error("Failed to write_all: {0}")]
WriteAll(io::Error), WriteAll(#[source] io::Error),
#[error("Unsupported request: {0}")] #[error("Unsupported request: {0}")]
Unsupported(u32), Unsupported(u32),
#[error("Failed to submit io uring: {0}")] #[error("Failed to submit io uring: {0}")]
SubmitIoUring(io::Error), SubmitIoUring(#[source] io::Error),
#[error("Failed to get guest address: {0}")] #[error("Failed to get guest address: {0}")]
GetHostAddress(GuestMemoryError), GetHostAddress(#[source] GuestMemoryError),
#[error("Failed to async read: {0}")] #[error("Failed to async read: {0}")]
AsyncRead(AsyncIoError), AsyncRead(#[source] AsyncIoError),
#[error("Failed to async write: {0}")] #[error("Failed to async write: {0}")]
AsyncWrite(AsyncIoError), AsyncWrite(#[source] AsyncIoError),
#[error("failed to async flush: {0}")] #[error("failed to async flush: {0}")]
AsyncFlush(AsyncIoError), AsyncFlush(#[source] AsyncIoError),
#[error("Failed allocating a temporary buffer: {0}")] #[error("Failed allocating a temporary buffer: {0}")]
TemporaryBufferAllocation(io::Error), TemporaryBufferAllocation(#[source] io::Error),
} }
impl ExecuteError { impl ExecuteError {
+18 -18
View File
@@ -37,23 +37,23 @@ const MAX_NESTING_DEPTH: u32 = 10;
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum Error { pub enum Error {
#[error("Backing file io error: {0}")] #[error("Backing file io error: {0}")]
BackingFileIo(io::Error), BackingFileIo(#[source] io::Error),
#[error("Backing file open error: {0}")] #[error("Backing file open error: {0}")]
BackingFileOpen(Box<Error>), BackingFileOpen(#[source] Box<Error>),
#[error("Backing file name is too long: {0} bytes over")] #[error("Backing file name is too long: {0} bytes over")]
BackingFileTooLong(usize), BackingFileTooLong(usize),
#[error("Compressed blocks not supported")] #[error("Compressed blocks not supported")]
CompressedBlocksNotSupported, CompressedBlocksNotSupported,
#[error("Failed to evict cache: {0}")] #[error("Failed to evict cache: {0}")]
EvictingCache(io::Error), EvictingCache(#[source] io::Error),
#[error("File larger than max of {MAX_QCOW_FILE_SIZE}: {0}")] #[error("File larger than max of {MAX_QCOW_FILE_SIZE}: {0}")]
FileTooBig(u64), FileTooBig(u64),
#[error("Failed to get file size: {0}")] #[error("Failed to get file size: {0}")]
GettingFileSize(io::Error), GettingFileSize(#[source] io::Error),
#[error("Failed to get refcount: {0}")] #[error("Failed to get refcount: {0}")]
GettingRefcount(refcount::Error), GettingRefcount(#[source] refcount::Error),
#[error("Failed to parse filename: {0}")] #[error("Failed to parse filename: {0}")]
InvalidBackingFileName(str::Utf8Error), InvalidBackingFileName(#[source] str::Utf8Error),
#[error("Invalid cluster index")] #[error("Invalid cluster index")]
InvalidClusterIndex, InvalidClusterIndex,
#[error("Invalid cluster size")] #[error("Invalid cluster size")]
@@ -81,29 +81,29 @@ pub enum Error {
#[error("Not enough space for refcounts")] #[error("Not enough space for refcounts")]
NotEnoughSpaceForRefcounts, NotEnoughSpaceForRefcounts,
#[error("Failed to open file {0}")] #[error("Failed to open file {0}")]
OpeningFile(io::Error), OpeningFile(#[source] io::Error),
#[error("Failed to read data: {0}")] #[error("Failed to read data: {0}")]
ReadingData(io::Error), ReadingData(#[source] io::Error),
#[error("Failed to read header: {0}")] #[error("Failed to read header: {0}")]
ReadingHeader(io::Error), ReadingHeader(#[source] io::Error),
#[error("Failed to read pointers: {0}")] #[error("Failed to read pointers: {0}")]
ReadingPointers(io::Error), ReadingPointers(#[source] io::Error),
#[error("Failed to read ref count block: {0}")] #[error("Failed to read ref count block: {0}")]
ReadingRefCountBlock(refcount::Error), ReadingRefCountBlock(#[source] refcount::Error),
#[error("Failed to read ref counts: {0}")] #[error("Failed to read ref counts: {0}")]
ReadingRefCounts(io::Error), ReadingRefCounts(#[source] io::Error),
#[error("Failed to rebuild ref counts: {0}")] #[error("Failed to rebuild ref counts: {0}")]
RebuildingRefCounts(io::Error), RebuildingRefCounts(#[source] io::Error),
#[error("Refcount table offset past file end")] #[error("Refcount table offset past file end")]
RefcountTableOffEnd, RefcountTableOffEnd,
#[error("Too many clusters specified for refcount")] #[error("Too many clusters specified for refcount")]
RefcountTableTooLarge, RefcountTableTooLarge,
#[error("Failed to seek file: {0}")] #[error("Failed to seek file: {0}")]
SeekingFile(io::Error), SeekingFile(#[source] io::Error),
#[error("Failed to set file size: {0}")] #[error("Failed to set file size: {0}")]
SettingFileSize(io::Error), SettingFileSize(#[source] io::Error),
#[error("Failed to set refcount refcount: {0}")] #[error("Failed to set refcount refcount: {0}")]
SettingRefcountRefcount(io::Error), SettingRefcountRefcount(#[source] io::Error),
#[error("Size too small for number of clusters")] #[error("Size too small for number of clusters")]
SizeTooSmallForNumberOfClusters, SizeTooSmallForNumberOfClusters,
#[error("L1 entry table too large: {0}")] #[error("L1 entry table too large: {0}")]
@@ -115,9 +115,9 @@ pub enum Error {
#[error("Unsupported version: {0}")] #[error("Unsupported version: {0}")]
UnsupportedVersion(u32), UnsupportedVersion(u32),
#[error("Failed to write data: {0}")] #[error("Failed to write data: {0}")]
WritingData(io::Error), WritingData(#[source] io::Error),
#[error("Failed to write header: {0}")] #[error("Failed to write header: {0}")]
WritingHeader(io::Error), WritingHeader(#[source] io::Error),
} }
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
+2 -2
View File
@@ -16,7 +16,7 @@ use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache};
pub enum Error { pub enum Error {
/// `EvictingCache` - Error writing a refblock from the cache to disk. /// `EvictingCache` - Error writing a refblock from the cache to disk.
#[error("Failed to write a refblock from the cache to disk: {0}")] #[error("Failed to write a refblock from the cache to disk: {0}")]
EvictingRefCounts(io::Error), EvictingRefCounts(#[source] io::Error),
/// `InvalidIndex` - Address requested isn't within the range of the disk. /// `InvalidIndex` - Address requested isn't within the range of the disk.
#[error("Address requested is not within the range of the disk")] #[error("Address requested is not within the range of the disk")]
InvalidIndex, InvalidIndex,
@@ -28,7 +28,7 @@ pub enum Error {
NeedNewCluster, NeedNewCluster,
/// `ReadingRefCounts` - Error reading the file into the refcount cache. /// `ReadingRefCounts` - Error reading the file into the refcount cache.
#[error("Failed to read the file into the refcount cache: {0}")] #[error("Failed to read the file into the refcount cache: {0}")]
ReadingRefCounts(io::Error), ReadingRefCounts(#[source] io::Error),
} }
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
+7 -7
View File
@@ -26,19 +26,19 @@ mod vhdx_metadata;
#[sorted] #[sorted]
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum VhdxError { pub enum VhdxError {
#[error("Not a VHDx file {0}")] #[error("Not a VHDx file: {0}")]
NotVhdx(#[source] VhdxHeaderError), NotVhdx(#[source] VhdxHeaderError),
#[error("Failed to parse VHDx header {0}")] #[error("Failed to parse VHDx header: {0}")]
ParseVhdxHeader(#[source] VhdxHeaderError), ParseVhdxHeader(#[source] VhdxHeaderError),
#[error("Failed to parse VHDx metadata {0}")] #[error("Failed to parse VHDx metadata: {0}")]
ParseVhdxMetadata(#[source] VhdxMetadataError), ParseVhdxMetadata(#[source] VhdxMetadataError),
#[error("Failed to parse VHDx region entries {0}")] #[error("Failed to parse VHDx region entries: {0}")]
ParseVhdxRegionEntry(#[source] VhdxHeaderError), ParseVhdxRegionEntry(#[source] VhdxHeaderError),
#[error("Failed reading metadata {0}")] #[error("Failed reading metadata: {0}")]
ReadBatEntry(#[source] VhdxBatError), ReadBatEntry(#[source] VhdxBatError),
#[error("Failed reading sector from disk {0}")] #[error("Failed reading sector from disk: {0}")]
ReadFailed(#[source] VhdxIoError), ReadFailed(#[source] VhdxIoError),
#[error("Failed writing to sector on disk {0}")] #[error("Failed writing to sector on disk: {0}")]
WriteFailed(#[source] VhdxIoError), WriteFailed(#[source] VhdxIoError),
} }
+2 -2
View File
@@ -33,9 +33,9 @@ pub enum VhdxBatError {
InvalidBatEntry, InvalidBatEntry,
#[error("Invalid BAT entry count")] #[error("Invalid BAT entry count")]
InvalidEntryCount, InvalidEntryCount,
#[error("Failed to read BAT entry {0}")] #[error("Failed to read BAT entry: {0}")]
ReadBat(#[source] io::Error), ReadBat(#[source] io::Error),
#[error("Failed to write BAT entry {0}")] #[error("Failed to write BAT entry: {0}")]
WriteBat(#[source] io::Error), WriteBat(#[source] io::Error),
} }