Skip to content

Commit fae67df

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 fae67df

File tree

10 files changed

+112
-202
lines changed

10 files changed

+112
-202
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/error.rs

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

src/ipc.rs

Lines changed: 8 additions & 64 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.
@@ -248,16 +197,12 @@ where
248197
{
249198
/// Blocking receive.
250199
pub fn recv(&self) -> Result<T, IpcError> {
251-
self.os_receiver.recv()?.to().map_err(IpcError::Bincode)
200+
self.os_receiver.recv()?.to()
252201
}
253202

254203
/// Non-blocking receive
255204
pub fn try_recv(&self) -> Result<T, TryRecvError> {
256-
self.os_receiver
257-
.try_recv()?
258-
.to()
259-
.map_err(IpcError::Bincode)
260-
.map_err(TryRecvError::IpcError)
205+
self.os_receiver.try_recv()?.to().map_err(|e| e.into())
261206
}
262207

263208
/// Blocks for up to the specified duration attempting to receive a message.
@@ -270,8 +215,7 @@ where
270215
self.os_receiver
271216
.try_recv_timeout(duration)?
272217
.to()
273-
.map_err(IpcError::Bincode)
274-
.map_err(TryRecvError::IpcError)
218+
.map_err(|e| e.into())
275219
}
276220

277221
/// Erase the type of the channel.
@@ -364,7 +308,7 @@ where
364308
}
365309

366310
/// Send data across the channel to the receiver.
367-
pub fn send(&self, data: T) -> Result<(), bincode::Error> {
311+
pub fn send(&self, data: T) -> Result<(), IpcError> {
368312
let mut bytes = Vec::with_capacity(4096);
369313
OS_IPC_CHANNELS_FOR_SERIALIZATION.with(|os_ipc_channels_for_serialization| {
370314
OS_IPC_SHARED_MEMORY_REGIONS_FOR_SERIALIZATION.with(
@@ -726,7 +670,7 @@ impl IpcMessage {
726670
}
727671

728672
/// Deserialize the raw data in the contained message into the inferred type.
729-
pub fn to<T>(mut self) -> Result<T, bincode::Error>
673+
pub fn to<T>(mut self) -> Result<T, IpcError>
730674
where
731675
T: for<'de> Deserialize<'de> + Serialize,
732676
{
@@ -744,7 +688,7 @@ impl IpcMessage {
744688
.map(Some)
745689
.collect(),
746690
);
747-
let result = bincode::deserialize(&self.data[..]);
691+
let result = bincode::deserialize(&self.data[..]).map_err(|e| e.into());
748692
*os_ipc_shared_memory_regions_for_deserialization.borrow_mut() =
749693
old_ipc_shared_memory_regions_for_deserialization;
750694
mem::swap(
@@ -886,7 +830,7 @@ where
886830
))
887831
}
888832

889-
pub fn accept(self) -> Result<(IpcReceiver<T>, T), bincode::Error> {
833+
pub fn accept(self) -> Result<(IpcReceiver<T>, T), IpcError> {
890834
let (os_receiver, ipc_message) = self.os_server.accept()?;
891835
Ok((
892836
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
}

0 commit comments

Comments
 (0)