1use crate::protos::comms::Message;
2use lucet_runtime_internals;
3use lucet_wasi::host;
4use protobuf;
5use std::error;
6use std::fmt;
7use std::io;
8use std::io::ErrorKind;
9use std::sync;
10
11pub type Result<T> = std::result::Result<T, Error>;
12
13#[derive(Debug)]
14pub enum Error {
15 DescriptorDoesntExist,
16 InvalidStartup(Message),
17 Io(io::Error),
18 Proto(protobuf::error::ProtobufError),
19 MpscRecv(sync::mpsc::RecvError),
20 MpscSend(sync::mpsc::SendError<Message>),
21 Lucet(lucet_runtime_internals::error::Error),
22 WasiErr(u16),
23}
24
25impl Error {
26 pub fn to_wasi_err(&self) -> u32 {
27 match self {
28 Error::Io(ref e) => match e.kind() {
29 ErrorKind::NotFound => host::__WASI_ENOENT,
30 ErrorKind::PermissionDenied => host::__WASI_EACCES,
31 ErrorKind::ConnectionRefused => host::__WASI_ECONNREFUSED,
32 ErrorKind::ConnectionReset => host::__WASI_ECONNRESET,
33 ErrorKind::ConnectionAborted => host::__WASI_ECONNABORTED,
34 ErrorKind::NotConnected => host::__WASI_ENOTCONN,
35 ErrorKind::AddrInUse => host::__WASI_EADDRINUSE,
36 ErrorKind::AddrNotAvailable => host::__WASI_EADDRNOTAVAIL,
37 ErrorKind::BrokenPipe => host::__WASI_EPIPE,
38 ErrorKind::AlreadyExists => host::__WASI_EEXIST,
39 ErrorKind::WouldBlock => host::__WASI_EAGAIN,
40 ErrorKind::InvalidInput | ErrorKind::InvalidData => host::__WASI_EINVAL,
41 ErrorKind::TimedOut => host::__WASI_ETIMEDOUT,
42 ErrorKind::Interrupted => host::__WASI_EINTR,
43 ErrorKind::WriteZero | ErrorKind::Other | ErrorKind::UnexpectedEof | _ => {
44 host::__WASI_EIO
45 }
46 },
47 Error::WasiErr(ref e) => u32::from(*e),
48 _ => 0,
49 }
50 }
51}
52
53impl fmt::Display for Error {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 match *self {
56 Self::DescriptorDoesntExist => write!(f, "Id doesn't exist"),
57 Self::InvalidStartup(ref msg) => write!(f, "Invalid startup message {:?}", msg),
58 Self::Io(ref e) => e.fmt(f),
59 Self::Proto(ref e) => e.fmt(f),
60 Self::MpscRecv(ref e) => e.fmt(f),
61 Self::MpscSend(ref e) => e.fmt(f),
62 Self::Lucet(ref e) => e.fmt(f),
63 Self::WasiErr(ref e) => e.fmt(f),
64 }
65 }
66}
67
68impl error::Error for Error {
69 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
70 match *self {
71 Self::DescriptorDoesntExist => None,
72 Self::InvalidStartup(_) => None,
73 Self::Io(ref e) => Some(e),
74 Self::Proto(ref e) => Some(e),
75 Self::MpscRecv(ref e) => Some(e),
76 Self::MpscSend(ref e) => Some(e),
77 Self::WasiErr(ref _e) => None,
78 Self::Lucet(ref _e) => None,
81 }
82 }
83}
84
85impl From<io::Error> for Error {
86 fn from(err: io::Error) -> Self {
87 Self::Io(err)
88 }
89}
90
91impl From<u16> for Error {
92 fn from(err: u16) -> Self {
93 Self::WasiErr(err)
94 }
95}
96
97impl From<sync::mpsc::RecvError> for Error {
98 fn from(err: sync::mpsc::RecvError) -> Self {
99 Self::MpscRecv(err)
100 }
101}
102impl From<sync::mpsc::SendError<Message>> for Error {
103 fn from(err: sync::mpsc::SendError<Message>) -> Self {
104 Self::MpscSend(err)
105 }
106}
107impl From<protobuf::error::ProtobufError> for Error {
108 fn from(err: protobuf::error::ProtobufError) -> Self {
109 Self::Proto(err)
110 }
111}
112
113impl From<lucet_runtime_internals::error::Error> for Error {
114 fn from(err: lucet_runtime_internals::error::Error) -> Self {
115 Self::Lucet(err)
116 }
117}