1use bitwarden_error::bitwarden_error;
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5use crate::{endpoint::Endpoint, rpc::error::RpcError};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum ErrorKind {
10 Fatal,
12 Unreachable,
15 Other,
18}
19
20pub trait IpcErrorKind {
37 fn kind(&self) -> ErrorKind;
40}
41
42impl IpcErrorKind for std::convert::Infallible {
43 fn kind(&self) -> ErrorKind {
44 match *self {}
46 }
47}
48
49#[cfg(any(test, feature = "test-support"))]
50impl IpcErrorKind for () {
51 fn kind(&self) -> ErrorKind {
52 ErrorKind::Other
53 }
54}
55
56#[derive(Debug, Error, Clone, PartialEq, Eq)]
59#[error("IPC client is already running")]
60#[bitwarden_error(basic)]
61pub struct AlreadyRunningError;
62
63#[derive(Debug, Error, Clone, PartialEq, Eq, Serialize, Deserialize)]
65#[bitwarden_ffi::wasm_record]
66pub enum SendError {
67 #[error("Destination unreachable")]
69 Unreachable,
70 #[error("{0}")]
72 Other(String),
73}
74
75#[derive(Debug, Error, Clone, PartialEq, Eq)]
79#[bitwarden_error(flat)]
80pub enum BroadcastError {
81 #[error("The communication backend does not support broadcasting to this group")]
83 Unsupported,
84 #[error("Delegating delivery to another endpoint is not supported")]
86 DelegationUnsupported,
87 #[error("The communication backend resolved the group to an endpoint outside of it: {0:?}")]
89 OutOfScope(Endpoint),
90 #[error("Failed to serialize payload: {0}")]
92 Serialization(String),
93}
94
95#[derive(Debug, Error, Clone, PartialEq, Eq)]
96#[bitwarden_error(flat)]
97#[allow(missing_docs)]
98pub enum SubscribeError {
99 #[error("The IPC processing thread is not running")]
100 NotStarted,
101}
102
103#[derive(Debug, Error, PartialEq, Eq)]
104#[bitwarden_error(flat)]
105#[allow(missing_docs)]
106pub enum ReceiveError {
107 #[error("Failed to subscribe to the IPC channel: {0}")]
108 Channel(#[from] tokio::sync::broadcast::error::RecvError),
109
110 #[error("Timed out while waiting for a message: {0}")]
111 Timeout(#[from] bitwarden_threading::time::ElapsedError),
112
113 #[error("Cancelled while waiting for a message")]
114 Cancelled,
115}
116
117#[derive(Debug, Error, PartialEq, Eq)]
118#[bitwarden_error(flat)]
119#[allow(missing_docs)]
120pub enum TypedReceiveError {
121 #[error("Failed to subscribe to the IPC channel: {0}")]
122 Channel(#[from] tokio::sync::broadcast::error::RecvError),
123
124 #[error("Timed out while waiting for a message: {0}")]
125 Timeout(#[from] bitwarden_threading::time::ElapsedError),
126
127 #[error("Cancelled while waiting for a message")]
128 Cancelled,
129
130 #[error("Typing error: {0}")]
131 Typing(String),
132}
133
134impl From<ReceiveError> for TypedReceiveError {
135 fn from(value: ReceiveError) -> Self {
136 match value {
137 ReceiveError::Channel(e) => TypedReceiveError::Channel(e),
138 ReceiveError::Timeout(e) => TypedReceiveError::Timeout(e),
139 ReceiveError::Cancelled => TypedReceiveError::Cancelled,
140 }
141 }
142}
143
144#[derive(Debug, Error, PartialEq, Eq)]
145#[bitwarden_error(flat)]
146#[allow(missing_docs)]
147pub enum RequestError {
148 #[error(transparent)]
149 Subscribe(#[from] SubscribeError),
150
151 #[error(transparent)]
152 Receive(#[from] TypedReceiveError),
153
154 #[error("Timed out while waiting for a message: {0}")]
155 Timeout(#[from] bitwarden_threading::time::ElapsedError),
156
157 #[error("Failed to send message: {0}")]
158 Send(String),
159
160 #[error("Destination unreachable")]
161 Unreachable,
162
163 #[error("Error occurred on the remote target: {0}")]
164 Rpc(#[from] RpcError),
165}
166
167impl From<SendError> for RequestError {
168 fn from(error: SendError) -> Self {
169 match error {
170 SendError::Unreachable => RequestError::Unreachable,
171 SendError::Other(message) => RequestError::Send(message),
172 }
173 }
174}