Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Error::io_error_kind #1026

Merged
merged 1 commit into from Jun 16, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 53 additions & 2 deletions src/error.rs
Expand Up @@ -9,6 +9,8 @@ use core::str::FromStr;
use serde::{de, ser};
#[cfg(feature = "std")]
use std::error;
#[cfg(feature = "std")]
use std::io::ErrorKind;

/// This type represents all possible errors that can occur when serializing or
/// deserializing JSON data.
Expand Down Expand Up @@ -105,6 +107,55 @@ impl Error {
pub fn is_eof(&self) -> bool {
self.classify() == Category::Eof
}

/// The kind reported by the underlying standard library I/O error, if this
/// error was caused by a failure to read or write bytes on an I/O stream.
///
/// # Example
///
/// ```
/// use serde_json::Value;
/// use std::io::{self, ErrorKind, Read};
/// use std::process;
///
/// struct ReaderThatWillTimeOut<'a>(&'a [u8]);
///
/// impl<'a> Read for ReaderThatWillTimeOut<'a> {
/// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
/// if self.0.is_empty() {
/// Err(io::Error::new(ErrorKind::TimedOut, "timed out"))
/// } else {
/// self.0.read(buf)
/// }
/// }
/// }
///
/// fn main() {
/// let reader = ReaderThatWillTimeOut(br#" {"k": "#);
///
/// let _: Value = match serde_json::from_reader(reader) {
/// Ok(value) => value,
/// Err(error) => {
/// if error.io_error_kind() == Some(ErrorKind::TimedOut) {
/// // Maybe this application needs to retry certain kinds of errors.
///
/// # return;
/// } else {
/// eprintln!("error: {}", error);
/// process::exit(1);
/// }
/// }
/// };
/// }
/// ```
#[cfg(feature = "std")]
pub fn io_error_kind(&self) -> Option<ErrorKind> {
if let ErrorCode::Io(io_error) = &self.err.code {
Some(io_error.kind())
} else {
None
}
}
}

/// Categorizes the cause of a `serde_json::Error`.
Expand Down Expand Up @@ -166,8 +217,8 @@ impl From<Error> for io::Error {
} else {
match j.classify() {
Category::Io => unreachable!(),
Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j),
Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j),
Category::Syntax | Category::Data => io::Error::new(ErrorKind::InvalidData, j),
Category::Eof => io::Error::new(ErrorKind::UnexpectedEof, j),
}
}
}
Expand Down