Skip to content

Commit 512913c

Browse files
committed
Unify error handling to have IpcError and TryRecvError be the main error
types. These types will give the Bincode error, Io errors (which are converted from platform errors) and Disconnect. Additionally we now use the thiserror crate which removes some of the code. Signed-off-by: Narfinger <[email protected]>
1 parent d918d57 commit 512913c

File tree

10 files changed

+112
-193
lines changed

10 files changed

+112
-193
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ futures-channel = { version = "0.3.31", optional = true }
3838
futures-core = { version = "0.3.31", optional = true }
3939
libc = "0.2.162"
4040
serde = { version = "1.0", features = ["rc"] }
41+
thiserror = "2.0.12"
4142
uuid = { version = "1", features = ["v4"] }
4243

4344
[target.'cfg(any(target_os = "linux", target_os = "openbsd", target_os = "freebsd", target_os = "illumos"))'.dependencies]

src/asynch.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use crate::ipc::{
1111
self, IpcMessage, IpcReceiver, IpcReceiverSet, IpcSelectionResult, IpcSender, OpaqueIpcReceiver,
1212
};
13+
use crate::IpcError;
1314
use futures_channel::mpsc::UnboundedReceiver;
1415
use futures_channel::mpsc::UnboundedSender;
1516
use futures_core::stream::FusedStream;
@@ -96,7 +97,7 @@ impl<T> Stream for IpcStream<T>
9697
where
9798
T: for<'de> Deserialize<'de> + Serialize,
9899
{
99-
type Item = Result<T, bincode::Error>;
100+
type Item = Result<T, IpcError>;
100101

101102
fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Option<Self::Item>> {
102103
let recv = Pin::new(&mut self.0);

src/error.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use std::io;
2+
3+
use thiserror::Error;
4+
5+
#[derive(Debug, Error)]
6+
#[non_exhaustive]
7+
pub enum SerializationError {}
8+
9+
#[derive(Debug, Error)]
10+
pub enum IpcError {
11+
#[error("Error in decoding or encoding: {0}")]
12+
Bincode(#[from] bincode::Error),
13+
#[error("Error in IO: {0}")]
14+
Io(#[from] io::Error),
15+
#[error("Ipc Disconnected")]
16+
Disconnected,
17+
}
18+
19+
#[derive(Debug, Error)]
20+
pub enum TryRecvError {
21+
#[error("IPC error")]
22+
IpcError(#[from] IpcError),
23+
#[error("Channel empty")]
24+
Empty,
25+
}

src/ipc.rs

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use crate::platform::{self, OsIpcChannel, OsIpcReceiver, OsIpcReceiverSet, OsIpc
1111
use crate::platform::{
1212
OsIpcOneShotServer, OsIpcSelectionResult, OsIpcSharedMemory, OsOpaqueIpcChannel,
1313
};
14+
use crate::{IpcError, TryRecvError};
1415

1516
use bincode;
1617
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
1718
use std::cell::RefCell;
1819
use std::cmp::min;
19-
use std::error::Error as StdError;
2020
use std::fmt::{self, Debug, Formatter};
2121
use std::io;
2222
use std::marker::PhantomData;
@@ -37,57 +37,6 @@ thread_local! {
3737
const { RefCell::new(Vec::new()) }
3838
}
3939

40-
#[derive(Debug)]
41-
pub enum IpcError {
42-
Bincode(bincode::Error),
43-
Io(io::Error),
44-
Disconnected,
45-
}
46-
47-
impl fmt::Display for IpcError {
48-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
49-
match *self {
50-
IpcError::Bincode(ref err) => write!(fmt, "bincode error: {err}"),
51-
IpcError::Io(ref err) => write!(fmt, "io error: {err}"),
52-
IpcError::Disconnected => write!(fmt, "disconnected"),
53-
}
54-
}
55-
}
56-
57-
impl StdError for IpcError {
58-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
59-
match *self {
60-
IpcError::Bincode(ref err) => Some(err),
61-
IpcError::Io(ref err) => Some(err),
62-
IpcError::Disconnected => None,
63-
}
64-
}
65-
}
66-
67-
#[derive(Debug)]
68-
pub enum TryRecvError {
69-
IpcError(IpcError),
70-
Empty,
71-
}
72-
73-
impl fmt::Display for TryRecvError {
74-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
75-
match *self {
76-
TryRecvError::IpcError(ref err) => write!(fmt, "ipc error: {err}"),
77-
TryRecvError::Empty => write!(fmt, "empty"),
78-
}
79-
}
80-
}
81-
82-
impl StdError for TryRecvError {
83-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
84-
match *self {
85-
TryRecvError::IpcError(ref err) => Some(err),
86-
TryRecvError::Empty => None,
87-
}
88-
}
89-
}
90-
9140
/// Create a connected [IpcSender] and [IpcReceiver] that
9241
/// transfer messages of a given type provided by type `T`
9342
/// or inferred by the types of messages sent by the sender.
@@ -364,7 +313,7 @@ where
364313
}
365314

366315
/// Send data across the channel to the receiver.
367-
pub fn send(&self, data: T) -> Result<(), bincode::Error> {
316+
pub fn send(&self, data: T) -> Result<(), IpcError> {
368317
let mut bytes = Vec::with_capacity(4096);
369318
OS_IPC_CHANNELS_FOR_SERIALIZATION.with(|os_ipc_channels_for_serialization| {
370319
OS_IPC_SHARED_MEMORY_REGIONS_FOR_SERIALIZATION.with(
@@ -744,7 +693,7 @@ impl IpcMessage {
744693
.map(Some)
745694
.collect(),
746695
);
747-
let result = bincode::deserialize(&self.data[..]);
696+
let result = bincode::deserialize(&self.data[..]).map_err(|e| e.into());
748697
*os_ipc_shared_memory_regions_for_deserialization.borrow_mut() =
749698
old_ipc_shared_memory_regions_for_deserialization;
750699
mem::swap(
@@ -886,7 +835,7 @@ where
886835
))
887836
}
888837

889-
pub fn accept(self) -> Result<(IpcReceiver<T>, T), bincode::Error> {
838+
pub fn accept(self) -> Result<(IpcReceiver<T>, T), IpcError> {
890839
let (os_receiver, ipc_message) = self.os_server.accept()?;
891840
Ok((
892841
IpcReceiver {

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ pub mod asynch;
3232
#[cfg(all(not(feature = "force-inprocess"), target_os = "windows"))]
3333
extern crate windows;
3434

35+
mod error;
3536
pub mod ipc;
3637
pub mod platform;
3738
pub mod router;
3839

3940
#[cfg(test)]
4041
mod test;
4142

42-
pub use bincode::{Error, ErrorKind};
43+
pub use error::{IpcError, TryRecvError};

src/platform/inprocess/mod.rs

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,19 @@
77
// option. This file may not be copied, modified, or distributed
88
// except according to those terms.
99

10-
use crate::ipc::{self, IpcMessage};
11-
use bincode;
10+
use crate::ipc::IpcMessage;
1211
use crossbeam_channel::{self, Receiver, RecvTimeoutError, Select, Sender, TryRecvError};
1312
use std::cell::{Ref, RefCell};
1413
use std::cmp::PartialEq;
1514
use std::collections::hash_map::HashMap;
16-
use std::error::Error as StdError;
1715
use std::fmt::{self, Debug, Formatter};
1816
use std::io;
1917
use std::ops::{Deref, RangeFrom};
2018
use std::slice;
2119
use std::sync::{Arc, LazyLock, Mutex};
2220
use std::time::Duration;
2321
use std::usize;
22+
use thiserror::Error;
2423
use uuid::Uuid;
2524

2625
#[derive(Clone)]
@@ -387,11 +386,15 @@ impl OsIpcSharedMemory {
387386
}
388387
}
389388

390-
#[derive(Debug, PartialEq)]
389+
#[derive(Debug, PartialEq, Error)]
391390
pub enum ChannelError {
391+
#[error("Channel Closed")]
392392
ChannelClosedError,
393+
#[error("Broken Pipe")]
393394
BrokenPipeError,
395+
#[error("Channel Empty")]
394396
ChannelEmpty,
397+
#[error("Unknown Error")]
395398
UnknownError,
396399
}
397400

@@ -402,42 +405,23 @@ impl ChannelError {
402405
}
403406
}
404407

405-
impl fmt::Display for ChannelError {
406-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
407-
match *self {
408-
ChannelError::ChannelClosedError => write!(fmt, "channel closed"),
409-
ChannelError::BrokenPipeError => write!(fmt, "broken pipe"),
410-
ChannelError::ChannelEmpty => write!(fmt, "channel empty"),
411-
ChannelError::UnknownError => write!(fmt, "unknown error"),
412-
}
413-
}
414-
}
415-
416-
impl StdError for ChannelError {}
417-
418-
impl From<ChannelError> for bincode::Error {
419-
fn from(crossbeam_error: ChannelError) -> Self {
420-
io::Error::from(crossbeam_error).into()
421-
}
422-
}
423-
424-
impl From<ChannelError> for ipc::IpcError {
408+
impl From<ChannelError> for crate::IpcError {
425409
fn from(error: ChannelError) -> Self {
426410
match error {
427-
ChannelError::ChannelClosedError => ipc::IpcError::Disconnected,
428-
e => ipc::IpcError::Bincode(io::Error::from(e).into()),
411+
ChannelError::ChannelClosedError => crate::IpcError::Disconnected,
412+
e => crate::IpcError::Io(io::Error::from(e).into()),
429413
}
430414
}
431415
}
432416

433-
impl From<ChannelError> for ipc::TryRecvError {
417+
impl From<ChannelError> for crate::TryRecvError {
434418
fn from(error: ChannelError) -> Self {
435419
match error {
436420
ChannelError::ChannelClosedError => {
437-
ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected)
421+
crate::TryRecvError::IpcError(crate::IpcError::Disconnected)
438422
},
439-
ChannelError::ChannelEmpty => ipc::TryRecvError::Empty,
440-
e => ipc::TryRecvError::IpcError(ipc::IpcError::Bincode(io::Error::from(e).into())),
423+
ChannelError::ChannelEmpty => crate::TryRecvError::Empty,
424+
e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e).into())),
441425
}
442426
}
443427
}

src/platform/macos/mod.rs

Lines changed: 23 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ use self::mach_sys::{kern_return_t, mach_msg_body_t, mach_msg_header_t, mach_msg
1212
use self::mach_sys::{mach_msg_ool_descriptor_t, mach_msg_port_descriptor_t, mach_msg_type_name_t};
1313
use self::mach_sys::{mach_msg_timeout_t, mach_port_limits_t, mach_port_msgcount_t};
1414
use self::mach_sys::{mach_port_right_t, mach_port_t, mach_task_self_, vm_inherit_t};
15-
use crate::ipc::{self, IpcMessage};
15+
use crate::ipc::IpcMessage;
1616

17-
use bincode;
1817
use libc::{self, c_char, c_uint, c_void, size_t};
1918
use rand::{self, Rng};
2019
use std::cell::Cell;
2120
use std::convert::TryInto;
22-
use std::error::Error as StdError;
2321
use std::ffi::CString;
2422
use std::fmt::{self, Debug, Formatter};
2523
use std::io;
@@ -30,6 +28,7 @@ use std::ptr;
3028
use std::slice;
3129
use std::sync::RwLock;
3230
use std::time::Duration;
31+
use thiserror::Error;
3332

3433
mod mach_sys;
3534

@@ -997,43 +996,28 @@ impl Message {
997996
}
998997
}
999998

1000-
#[derive(Clone, Copy, Debug, PartialEq)]
999+
#[derive(Clone, Copy, Debug, Error, PartialEq)]
10011000
pub enum KernelError {
1001+
#[error("Success")]
10021002
Success,
1003+
#[error("No room in IPC name space for another right.")]
10031004
NoSpace,
1005+
#[error("Name doesn't denote a right in the task")]
10041006
InvalidName,
1007+
#[error("Name denotes a right, but not an appropiate right.")]
10051008
InvalidRight,
1009+
#[error("Blatant range error")]
10061010
InvalidValue,
1011+
#[error("The supplied (port) capability is improper")]
10071012
InvalidCapability,
1013+
#[error("Operation would overflow limit on user-references")]
10081014
UrefsOverflow,
1015+
#[error("Receive right is not a member of a port set.")]
10091016
NotInSet,
1017+
#[error("Unkown kernel error. {0}")]
10101018
Unknown(kern_return_t),
10111019
}
10121020

1013-
impl fmt::Display for KernelError {
1014-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1015-
match *self {
1016-
KernelError::Success => write!(fmt, "Success."),
1017-
KernelError::NoSpace => write!(fmt, "No room in IPC name space for another right."),
1018-
KernelError::InvalidName => write!(fmt, "Name doesn't denote a right in the task."),
1019-
KernelError::InvalidRight => {
1020-
write!(fmt, "Name denotes a right, but not an appropriate right.")
1021-
},
1022-
KernelError::InvalidValue => write!(fmt, "Blatant range error."),
1023-
KernelError::InvalidCapability => {
1024-
write!(fmt, "The supplied (port) capability is improper.")
1025-
},
1026-
KernelError::UrefsOverflow => {
1027-
write!(fmt, "Operation would overflow limit on user-references.")
1028-
},
1029-
KernelError::NotInSet => write!(fmt, "Receive right is not a member of a port set."),
1030-
KernelError::Unknown(code) => write!(fmt, "Unknown kernel error: {:x}", code),
1031-
}
1032-
}
1033-
}
1034-
1035-
impl StdError for KernelError {}
1036-
10371021
impl From<kern_return_t> for KernelError {
10381022
fn from(code: kern_return_t) -> KernelError {
10391023
match code {
@@ -1050,10 +1034,10 @@ impl From<kern_return_t> for KernelError {
10501034
}
10511035
}
10521036

1053-
#[derive(Clone, Copy, Debug, PartialEq)]
1037+
#[derive(Clone, Copy, Debug, Error, PartialEq)]
10541038
pub enum MachError {
10551039
Success,
1056-
Kernel(KernelError),
1040+
Kernel(#[from] KernelError),
10571041
IpcSpace,
10581042
VmSpace,
10591043
IpcKernel,
@@ -1185,14 +1169,6 @@ impl fmt::Display for MachError {
11851169
}
11861170
}
11871171

1188-
impl StdError for MachError {}
1189-
1190-
impl From<MachError> for bincode::Error {
1191-
fn from(mach_error: MachError) -> Self {
1192-
io::Error::from(mach_error).into()
1193-
}
1194-
}
1195-
11961172
impl From<mach_msg_return_t> for MachError {
11971173
fn from(code: mach_msg_return_t) -> MachError {
11981174
match code {
@@ -1240,27 +1216,23 @@ impl From<mach_msg_return_t> for MachError {
12401216
}
12411217
}
12421218

1243-
impl From<KernelError> for MachError {
1244-
fn from(kernel_error: KernelError) -> MachError {
1245-
MachError::Kernel(kernel_error)
1246-
}
1247-
}
1248-
1249-
impl From<MachError> for ipc::TryRecvError {
1219+
impl From<MachError> for crate::TryRecvError {
12501220
fn from(error: MachError) -> Self {
12511221
match error {
1252-
MachError::NotifyNoSenders => ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected),
1253-
MachError::RcvTimedOut => ipc::TryRecvError::Empty,
1254-
e => ipc::TryRecvError::IpcError(ipc::IpcError::Io(io::Error::from(e))),
1222+
MachError::NotifyNoSenders => {
1223+
crate::TryRecvError::IpcError(crate::IpcError::Disconnected)
1224+
},
1225+
MachError::RcvTimedOut => crate::TryRecvError::Empty,
1226+
e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e))),
12551227
}
12561228
}
12571229
}
12581230

1259-
impl From<MachError> for ipc::IpcError {
1231+
impl From<MachError> for crate::IpcError {
12601232
fn from(error: MachError) -> Self {
12611233
match error {
1262-
MachError::NotifyNoSenders => ipc::IpcError::Disconnected,
1263-
e => ipc::IpcError::Io(io::Error::from(e)),
1234+
MachError::NotifyNoSenders => crate::IpcError::Disconnected,
1235+
e => crate::IpcError::Io(io::Error::from(e)),
12641236
}
12651237
}
12661238
}

0 commit comments

Comments
 (0)