Skip to content

Commit

Permalink
Simplify error handling (#70)
Browse files Browse the repository at this point in the history
Merged `SendError`'s `MessageTooLarge` and `SerializationFailure`, and
`HandshakeError`'s `MessageTooLarge` and `SerializationFailure` into
`MessageTooLarge`, since serialization into a memory buffer fails only
when the message is too large.
  • Loading branch information
msk authored Apr 4, 2024
1 parent 91665eb commit 445e786
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 26 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).

- `SendError::MessageTooLarge` no longer contains the underlying error,
`std::num::TryFromIntError`, since it does not provide any useful information.
- Merge `SendError`'s `MessageTooLarge` and `SerializationFailure`, and
`HandshakeError`'s `MessageTooLarge` and `SerializationFailure` into
`MessageTooLarge`, since serialization into a memory buffer fails only when
the message is too large.

### Removed

Expand Down
7 changes: 3 additions & 4 deletions src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ pub async fn recv_raw<'b>(
/// The error type for sending a message as a frame.
#[derive(Debug, Error)]
pub enum SendError {
#[error("failed serializing message")]
SerializationFailure(#[from] bincode::Error),
#[error("message is too large")]
MessageTooLarge,
#[error("failed to write to a stream")]
Expand All @@ -71,15 +69,16 @@ pub enum SendError {
///
/// # Errors
///
/// * `SendError::SerializationFailure`: if the message could not be serialized
/// * `SendError::MessageTooLarge`: if the message is too large
/// * `SendError::WriteError`: if the message could not be written
pub async fn send<T>(send: &mut SendStream, buf: &mut Vec<u8>, msg: T) -> Result<(), SendError>
where
T: Serialize,
{
buf.resize(mem::size_of::<u32>(), 0);
bincode::DefaultOptions::new().serialize_into(&mut *buf, &msg)?;
bincode::DefaultOptions::new()
.serialize_into(&mut *buf, &msg)
.map_err(|_| SendError::MessageTooLarge)?;
let len = u32::try_from(buf.len() - 4).map_err(|_| SendError::MessageTooLarge)?;
buf[..mem::size_of::<u32>()].clone_from_slice(&len.to_be_bytes());
send.write_all(buf).await?;
Expand Down
31 changes: 9 additions & 22 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ pub enum HandshakeError {
ReadError(#[from] quinn::ReadError),
#[error("cannot send a message")]
WriteError(#[from] quinn::WriteError),
#[error("cannot serialize a message")]
SerializationFailure(#[from] bincode::Error),
#[error("arguments are too long")]
MessageTooLarge,
#[error("invalid message")]
Expand All @@ -59,7 +57,6 @@ pub enum HandshakeError {
impl From<SendError> for HandshakeError {
fn from(e: SendError) -> Self {
match e {
SendError::SerializationFailure(e) => HandshakeError::SerializationFailure(e),
SendError::MessageTooLarge => HandshakeError::MessageTooLarge,
SendError::WriteError(e) => HandshakeError::WriteError(e),
}
Expand All @@ -72,7 +69,7 @@ impl From<SendError> for HandshakeError {
///
/// # Errors
///
/// * `SendError::SerializationFailure` if the message could not be serialized
/// * `SendError::MessageTooLarge` if the message is too long to be serialized
/// * `SendError::WriteError` if the message could not be written
pub async fn send_request<C, B>(
send: &mut SendStream,
Expand All @@ -84,35 +81,25 @@ where
C: Into<u32>,
B: Serialize,
{
use std::io::Write;

buf.clear();
serialize_request(buf, code, body)?;
buf.extend_from_slice(&code.into().to_le_bytes());
bincode::DefaultOptions::new()
.serialize_into(buf as &mut dyn Write, &body)
.map_err(|_| SendError::MessageTooLarge)?;
frame::send_raw(send, buf).await?;
buf.clear();
Ok(())
}

/// Serializes the given request and appends it to `buf`.
///
/// # Errors
///
/// * `bincode::Error` if the message could not be serialized
fn serialize_request<C, B>(buf: &mut Vec<u8>, code: C, body: B) -> Result<(), bincode::Error>
where
C: Into<u32>,
B: Serialize,
{
buf.extend_from_slice(&code.into().to_le_bytes());
bincode::DefaultOptions::new().serialize_into(buf, &body)?;
Ok(())
}

/// Sends an `Ok` response.
///
/// `buf` will be cleared after the response is sent.
///
/// # Errors
///
/// * `SendError::SerializationFailure` if the message could not be serialized
/// * `SendError::MessageTooLarge` if `body` is too large to be serialized
/// * `SendError::WriteError` if the message could not be written
pub async fn send_ok<T: Serialize>(
send: &mut SendStream,
Expand All @@ -129,7 +116,7 @@ pub async fn send_ok<T: Serialize>(
///
/// # Errors
///
/// * `SendError::SerializationFailure` if the message could not be serialized
/// * `SendError::MessageTooLarge` if `e` is too large to be serialized
/// * `SendError::WriteError` if the message could not be written
pub async fn send_err<E: fmt::Display>(
send: &mut SendStream,
Expand Down

0 comments on commit 445e786

Please sign in to comment.