diff --git a/crates/wasi-common/src/error.rs b/crates/wasi-common/src/error.rs index 282a46734f..2b0fb5b7ac 100644 --- a/crates/wasi-common/src/error.rs +++ b/crates/wasi-common/src/error.rs @@ -17,6 +17,10 @@ pub enum Error { #[error("GetRandom: {0}")] GetRandom(#[from] getrandom::Error), + /// Some corners of the WASI standard are unsupported. + #[error("Unsupported: {0}")] + Unsupported(&'static str), + /// The host OS may return an io error that doesn't match one of the /// wasi errno variants we expect. We do not expose the details of this /// error to the user. diff --git a/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs b/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs index 74a39769bc..8bb41a903a 100644 --- a/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs +++ b/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs @@ -724,7 +724,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { } fn proc_raise(&self, _sig: types::Signal) -> Result<()> { - unimplemented!("proc_raise") + Err(Error::Unsupported("proc_raise")) } fn sched_yield(&self) -> Result<()> { @@ -744,7 +744,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { _ri_data: &types::IovecArray<'_>, _ri_flags: types::Riflags, ) -> Result<(types::Size, types::Roflags)> { - unimplemented!("sock_recv") + Err(Error::Unsupported("sock_recv")) } fn sock_send( @@ -753,11 +753,11 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { _si_data: &types::CiovecArray<'_>, _si_flags: types::Siflags, ) -> Result { - unimplemented!("sock_send") + Err(Error::Unsupported("sock_send")) } fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> { - unimplemented!("sock_shutdown") + Err(Error::Unsupported("sock_shutdown")) } } @@ -804,7 +804,7 @@ impl WasiCtx { Err(error) => { events.push(types::Event { userdata: subscription.userdata, - error: error.into(), + error: error.try_into().expect("non-trapping error"), type_: types::Eventtype::FdRead, fd_readwrite: types::EventFdReadwrite { nbytes: 0, @@ -830,7 +830,7 @@ impl WasiCtx { Err(error) => { events.push(types::Event { userdata: subscription.userdata, - error: error.into(), + error: error.try_into().expect("non-trapping error"), type_: types::Eventtype::FdWrite, fd_readwrite: types::EventFdReadwrite { nbytes: 0, diff --git a/crates/wasi-common/src/snapshots/wasi_unstable.rs b/crates/wasi-common/src/snapshots/wasi_unstable.rs index 9029dd6ae4..dbdef63e42 100644 --- a/crates/wasi-common/src/snapshots/wasi_unstable.rs +++ b/crates/wasi-common/src/snapshots/wasi_unstable.rs @@ -25,13 +25,14 @@ impl types::GuestErrorConversion for WasiCtx { impl types::UserErrorConversion for WasiCtx { fn errno_from_error(&self, e: Error) -> Result { tracing::debug!("Error: {:?}", e); - Ok(e.into()) + e.try_into() } } -impl From for Errno { - fn from(e: Error) -> Errno { - types_new::Errno::from(e).into() +impl TryFrom for Errno { + type Error = wiggle::Trap; + fn try_from(e: Error) -> Result { + Ok(types_new::Errno::try_from(e)?.into()) } } diff --git a/crates/wasi-common/src/sys/unix/poll.rs b/crates/wasi-common/src/sys/unix/poll.rs index 059391ab96..2b45c7110f 100644 --- a/crates/wasi-common/src/sys/unix/poll.rs +++ b/crates/wasi-common/src/sys/unix/poll.rs @@ -117,7 +117,7 @@ fn handle_fd_event( let output_event = if revents.contains(PollFlags::POLLNVAL) { Event { userdata: fd_event.userdata, - error: Error::Badf.into(), + error: Error::Badf.try_into().unwrap(), type_: fd_event.r#type, fd_readwrite: EventFdReadwrite { nbytes: 0, @@ -127,7 +127,7 @@ fn handle_fd_event( } else if revents.contains(PollFlags::POLLERR) { Event { userdata: fd_event.userdata, - error: Error::Io.into(), + error: Error::Io.try_into().unwrap(), type_: fd_event.r#type, fd_readwrite: EventFdReadwrite { nbytes: 0, diff --git a/crates/wasi-common/src/wasi.rs b/crates/wasi-common/src/wasi.rs index 1877bbf094..978d45d113 100644 --- a/crates/wasi-common/src/wasi.rs +++ b/crates/wasi-common/src/wasi.rs @@ -1,4 +1,5 @@ use crate::{Error, WasiCtx}; +use std::convert::{TryFrom, TryInto}; use tracing::debug; wiggle::from_witx!({ @@ -25,45 +26,49 @@ impl types::GuestErrorConversion for WasiCtx { impl types::UserErrorConversion for WasiCtx { fn errno_from_error(&self, e: Error) -> Result { debug!("Error: {:?}", e); - Ok(e.into()) + e.try_into() } } -impl From for Errno { - fn from(e: Error) -> Errno { +impl TryFrom for Errno { + type Error = wiggle::Trap; + fn try_from(e: Error) -> Result { match e { - Error::Guest(e) => e.into(), - Error::TryFromInt(_) => Errno::Overflow, - Error::Utf8(_) => Errno::Ilseq, - Error::UnexpectedIo(_) => Errno::Io, - Error::GetRandom(_) => Errno::Io, - Error::TooBig => Errno::TooBig, - Error::Acces => Errno::Acces, - Error::Badf => Errno::Badf, - Error::Busy => Errno::Busy, - Error::Exist => Errno::Exist, - Error::Fault => Errno::Fault, - Error::Fbig => Errno::Fbig, - Error::Ilseq => Errno::Ilseq, - Error::Inval => Errno::Inval, - Error::Io => Errno::Io, - Error::Isdir => Errno::Isdir, - Error::Loop => Errno::Loop, - Error::Mfile => Errno::Mfile, - Error::Mlink => Errno::Mlink, - Error::Nametoolong => Errno::Nametoolong, - Error::Nfile => Errno::Nfile, - Error::Noent => Errno::Noent, - Error::Nomem => Errno::Nomem, - Error::Nospc => Errno::Nospc, - Error::Notdir => Errno::Notdir, - Error::Notempty => Errno::Notempty, - Error::Notsup => Errno::Notsup, - Error::Overflow => Errno::Overflow, - Error::Pipe => Errno::Pipe, - Error::Perm => Errno::Perm, - Error::Spipe => Errno::Spipe, - Error::Notcapable => Errno::Notcapable, + Error::Guest(e) => Ok(e.into()), + Error::TryFromInt(_) => Ok(Errno::Overflow), + Error::Utf8(_) => Ok(Errno::Ilseq), + Error::UnexpectedIo(_) => Ok(Errno::Io), + Error::GetRandom(_) => Ok(Errno::Io), + Error::TooBig => Ok(Errno::TooBig), + Error::Acces => Ok(Errno::Acces), + Error::Badf => Ok(Errno::Badf), + Error::Busy => Ok(Errno::Busy), + Error::Exist => Ok(Errno::Exist), + Error::Fault => Ok(Errno::Fault), + Error::Fbig => Ok(Errno::Fbig), + Error::Ilseq => Ok(Errno::Ilseq), + Error::Inval => Ok(Errno::Inval), + Error::Io => Ok(Errno::Io), + Error::Isdir => Ok(Errno::Isdir), + Error::Loop => Ok(Errno::Loop), + Error::Mfile => Ok(Errno::Mfile), + Error::Mlink => Ok(Errno::Mlink), + Error::Nametoolong => Ok(Errno::Nametoolong), + Error::Nfile => Ok(Errno::Nfile), + Error::Noent => Ok(Errno::Noent), + Error::Nomem => Ok(Errno::Nomem), + Error::Nospc => Ok(Errno::Nospc), + Error::Notdir => Ok(Errno::Notdir), + Error::Notempty => Ok(Errno::Notempty), + Error::Notsup => Ok(Errno::Notsup), + Error::Overflow => Ok(Errno::Overflow), + Error::Pipe => Ok(Errno::Pipe), + Error::Perm => Ok(Errno::Perm), + Error::Spipe => Ok(Errno::Spipe), + Error::Notcapable => Ok(Errno::Notcapable), + Error::Unsupported(feature) => { + Err(wiggle::Trap::String(format!("unsupported: {}", feature))) + } } } } @@ -80,8 +85,8 @@ impl From for Errno { PtrBorrowed { .. } => Self::Fault, InvalidUtf8 { .. } => Self::Ilseq, TryFromIntError { .. } => Self::Overflow, - InFunc { .. } => Self::Inval, - InDataField { .. } => Self::Inval, + InFunc { err, .. } => Errno::from(*err), + InDataField { err, .. } => Errno::from(*err), SliceLengthsDiffer { .. } => Self::Fault, BorrowCheckerOutOfHandles { .. } => Self::Fault, }