1use zx::Status;
6
7#[derive(Debug)]
14pub enum DriverError {
15 Status(Status),
17 Anyhow(anyhow::Error),
19 Fidl(fidl::Error),
21}
22
23impl DriverError {
24 pub fn log_to_status(self) -> Status {
26 match self {
27 DriverError::Status(status) => status,
28 DriverError::Anyhow(err) => {
29 if let Some(status) = err.root_cause().downcast_ref::<Status>() {
30 *status
31 } else {
32 log::error!("Driver failed with internal error: {:?}", err);
33 Status::INTERNAL
34 }
35 }
36 DriverError::Fidl(err) => {
37 log::error!("Driver failed with FIDL error: {:?}", err);
38 Status::INTERNAL
39 }
40 }
41 }
42}
43
44impl From<Status> for DriverError {
45 fn from(status: Status) -> Self {
46 DriverError::Status(status)
47 }
48}
49
50impl From<anyhow::Error> for DriverError {
51 fn from(err: anyhow::Error) -> Self {
52 DriverError::Anyhow(err)
53 }
54}
55
56impl From<fidl::Error> for DriverError {
57 fn from(err: fidl::Error) -> Self {
58 DriverError::Fidl(err)
59 }
60}
61
62impl std::fmt::Display for DriverError {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 match self {
65 DriverError::Status(status) => write!(f, "Status: {status}"),
66 DriverError::Anyhow(err) => write!(f, "Anyhow: {err}"),
67 DriverError::Fidl(err) => write!(f, "FIDL: {err}"),
68 }
69 }
70}
71
72impl std::error::Error for DriverError {
73 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
74 match self {
75 DriverError::Status(status) => Some(status),
76 DriverError::Anyhow(err) => Some(err.as_ref()),
77 DriverError::Fidl(err) => Some(err),
78 }
79 }
80}
81
82impl From<fidl_next::Error<Status>> for DriverError {
83 fn from(err: fidl_next::Error<Status>) -> Self {
84 match err {
85 fidl_next::Error::Encode(encode_err) => {
86 log::error!("FIDL encode error: {:?}", encode_err);
87 DriverError::Status(Status::INTERNAL)
88 }
89 fidl_next::Error::Decode(decode_err) => {
90 log::error!("FIDL decode error: {:?}", decode_err);
91 DriverError::Status(Status::INTERNAL)
92 }
93 fidl_next::Error::Protocol(protocol_err) => match protocol_err {
94 fidl_next::ProtocolError::TransportError(status) => DriverError::Status(status),
95 fidl_next::ProtocolError::PeerClosed => DriverError::Status(Status::PEER_CLOSED),
96 _ => {
97 log::error!("FIDL protocol error: {:?}", protocol_err);
98 DriverError::Status(Status::INTERNAL)
99 }
100 },
101 }
102 }
103}