you program rust for a few years and you think you're done tearing your hair out over lifetimes, well, you'll find yourself wrong
142 lines
4.4 KiB
Rust
142 lines
4.4 KiB
Rust
//! `wasi_common::Error` is now `anyhow::Error`.
|
|
//!
|
|
//! Snapshots (right now only `wasi_common::snapshots::preview_1`) contains
|
|
//! all of the logic for transforming an `Error` into the snapshot's own
|
|
//! `Errno`. They may do so by downcasting the error into any of:
|
|
//! * `std::io::Error` - these are thrown by `std`, `cap_std`, etc for most of
|
|
//! the operations WASI is concerned with.
|
|
//! * `wasi_common::ErrorKind` - these are a subset of the Errnos, and are
|
|
//! constructed directly by wasi-common or an impl rather than coming from the
|
|
//! OS or some library which doesn't know about WASI.
|
|
//! * `wiggle::GuestError`
|
|
//! * `std::num::TryFromIntError`
|
|
//! * `std::str::Utf8Error`
|
|
//! and then applying specialized logic to translate each of those into
|
|
//! `Errno`s.
|
|
//!
|
|
//! The `wasi_common::ErrorExt` trait provides human-friendly constructors for
|
|
//! the `wasi_common::ErrorKind` variants .
|
|
//!
|
|
//! If you throw an error that does not downcast to one of those, it will turn
|
|
//! into a `wiggle::Trap` and terminate execution.
|
|
//!
|
|
//! The real value of using `anyhow::Error` here is being able to use
|
|
//! `anyhow::Result::context` to aid in debugging of errors.
|
|
|
|
pub use anyhow::{Context, Error};
|
|
|
|
/// Internal error type for the `wasi-common` crate.
|
|
/// Contains variants of the WASI `$errno` type are added according to what is actually used internally by
|
|
/// the crate. Not all values are represented presently.
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum ErrorKind {
|
|
/// Errno::Noent: No such file or directory
|
|
#[error("Noent: No such file or directory")]
|
|
Noent,
|
|
/// Errno::TooBig: Argument list too long
|
|
#[error("TooBig: Argument list too long")]
|
|
TooBig,
|
|
/// Errno::Badf: Bad file descriptor
|
|
#[error("Badf: Bad file descriptor")]
|
|
Badf,
|
|
/// Errno::Exist: File exists
|
|
#[error("Exist: File exists")]
|
|
Exist,
|
|
/// Errno::Ilseq: Illegal byte sequence
|
|
#[error("Ilseq: Illegal byte sequence")]
|
|
Ilseq,
|
|
/// Errno::Inval: Invalid argument
|
|
#[error("Inval: Invalid argument")]
|
|
Inval,
|
|
/// Errno::Io: I/O error
|
|
#[error("Io: I/O error")]
|
|
Io,
|
|
/// Errno::Nametoolong: Filename too long
|
|
#[error("Nametoolong: Filename too long")]
|
|
Nametoolong,
|
|
/// Errno::Notdir: Not a directory or a symbolic link to a directory.
|
|
#[error("Notdir: Not a directory or a symbolic link to a directory")]
|
|
Notdir,
|
|
/// Errno::Notsup: Not supported, or operation not supported on socket.
|
|
#[error("Notsup: Not supported, or operation not supported on socket")]
|
|
Notsup,
|
|
/// Errno::Overflow: Value too large to be stored in data type.
|
|
#[error("Overflow: Value too large to be stored in data type")]
|
|
Overflow,
|
|
/// Errno::Range: Result too large
|
|
#[error("Range: Result too large")]
|
|
Range,
|
|
/// Errno::Spipe: Invalid seek
|
|
#[error("Spipe: Invalid seek")]
|
|
Spipe,
|
|
/// Errno::NotCapable: Not capable
|
|
#[error("Not capable")]
|
|
NotCapable,
|
|
}
|
|
|
|
pub trait ErrorExt {
|
|
fn trap(msg: impl Into<String>) -> Self;
|
|
fn not_found() -> Self;
|
|
fn too_big() -> Self;
|
|
fn badf() -> Self;
|
|
fn exist() -> Self;
|
|
fn illegal_byte_sequence() -> Self;
|
|
fn invalid_argument() -> Self;
|
|
fn io() -> Self;
|
|
fn name_too_long() -> Self;
|
|
fn not_dir() -> Self;
|
|
fn not_supported() -> Self;
|
|
fn overflow() -> Self;
|
|
fn range() -> Self;
|
|
fn seek_pipe() -> Self;
|
|
fn not_capable() -> Self;
|
|
}
|
|
|
|
impl ErrorExt for Error {
|
|
fn trap(msg: impl Into<String>) -> Self {
|
|
anyhow::anyhow!(msg.into())
|
|
}
|
|
fn not_found() -> Self {
|
|
ErrorKind::Noent.into()
|
|
}
|
|
fn too_big() -> Self {
|
|
ErrorKind::TooBig.into()
|
|
}
|
|
fn badf() -> Self {
|
|
ErrorKind::Badf.into()
|
|
}
|
|
fn exist() -> Self {
|
|
ErrorKind::Exist.into()
|
|
}
|
|
fn illegal_byte_sequence() -> Self {
|
|
ErrorKind::Ilseq.into()
|
|
}
|
|
fn invalid_argument() -> Self {
|
|
ErrorKind::Inval.into()
|
|
}
|
|
fn io() -> Self {
|
|
ErrorKind::Io.into()
|
|
}
|
|
fn name_too_long() -> Self {
|
|
ErrorKind::Nametoolong.into()
|
|
}
|
|
fn not_dir() -> Self {
|
|
ErrorKind::Notdir.into()
|
|
}
|
|
fn not_supported() -> Self {
|
|
ErrorKind::Notsup.into()
|
|
}
|
|
fn overflow() -> Self {
|
|
ErrorKind::Overflow.into()
|
|
}
|
|
fn range() -> Self {
|
|
ErrorKind::Range.into()
|
|
}
|
|
fn seek_pipe() -> Self {
|
|
ErrorKind::Spipe.into()
|
|
}
|
|
fn not_capable() -> Self {
|
|
ErrorKind::NotCapable.into()
|
|
}
|
|
}
|