Skip to content

Commit

Permalink
Add Error::io_error_kind
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jun 16, 2023
1 parent 136b773 commit 9308d97
Showing 1 changed file with 53 additions and 2 deletions.
55 changes: 53 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
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

0 comments on commit 9308d97

Please sign in to comment.