Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ pub enum PushError {
Closed,
}

impl std::fmt::Display for PushError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::QueueFull => f.write_str("push queue full"),
Self::Closed => f.write_str("push queue closed"),
}
}
}

impl std::error::Error for PushError {}

pub(crate) struct PushHandleInner<F> {
high_prio_tx: mpsc::Sender<F>,
low_prio_tx: mpsc::Sender<F>,
Expand Down
21 changes: 21 additions & 0 deletions src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,24 @@ impl<E> WireframeError<E> {
#[must_use]
pub fn from_io(e: std::io::Error) -> Self { WireframeError::Io(e) }
}

impl<E: std::fmt::Debug> std::fmt::Display for WireframeError<E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
WireframeError::Io(e) => write!(f, "transport error: {e}"),
WireframeError::Protocol(e) => write!(f, "protocol error: {e:?}"),
Comment thread
leynos marked this conversation as resolved.
}
}
}

impl<E> std::error::Error for WireframeError<E>
where
E: std::fmt::Debug + std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Error::source returns None for Protocol even if E might implement Error.

Consider returning Some(e) for the Protocol variant if E implements Error. If returning None is intentional, please document the reasoning.

match self {
WireframeError::Io(e) => Some(e),
WireframeError::Protocol(e) => Some(e),
}
}
}
40 changes: 40 additions & 0 deletions tests/error_display.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! Tests for Display and Error trait implementations on error types.
//!
//! Verifies that error types provide human-readable messages via Display
//! and correctly expose underlying error sources via `Error::source`.

use std::error::Error;

use wireframe::{push::PushError, response::WireframeError};

#[rstest::rstest]
#[case(PushError::QueueFull, "push queue full")]
#[case(PushError::Closed, "push queue closed")]
fn push_error_messages(#[case] err: PushError, #[case] expected: &str) {
assert_eq!(err.to_string(), expected);
}

#[derive(Debug)]
struct ProtoErr;

impl std::fmt::Display for ProtoErr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("boom") }
}

impl std::error::Error for ProtoErr {}

#[test]
fn wireframe_error_messages() {
let io_error = std::io::Error::other("socket closed");
let io = WireframeError::<ProtoErr>::Io(io_error);
assert_eq!(io.to_string(), "transport error: socket closed");

let source = io.source().expect("io variant must have source");
assert_eq!(source.to_string(), "socket closed");

let proto = WireframeError::Protocol(ProtoErr);
assert_eq!(proto.to_string(), "protocol error: ProtoErr");

let source = proto.source().expect("protocol variant must have source");
assert_eq!(source.to_string(), "boom");
}