dtolnay / serde-yaml

Strongly typed YAML library for Rust
Apache License 2.0
964 stars 164 forks source link

Same message duplicated between source() and Display of serde_yaml::Error #359

Closed dtolnay closed 1 year ago

dtolnay commented 1 year ago
// [dependencies]
// anyhow = "1"
// serde = "1"
// serde_yaml = "0.9"

use serde::de::Deserialize;
use std::error::Error;
use std::fmt::{self, Display};
use std::io::{self, Read};

struct Reader;

#[derive(Debug)]
struct MyError;

impl Error for MyError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        Some(&std::sync::mpsc::RecvTimeoutError::Timeout)
    }
}

impl Display for MyError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("bad read")
    }
}

impl Read for Reader {
    fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
        Err(io::Error::new(io::ErrorKind::TimedOut, MyError))
    }
}

fn main() -> anyhow::Result<()> {
    let reader = Reader;
    let de = serde_yaml::Deserializer::from_reader(reader);
    let _ = u8::deserialize(de)?;
    Ok(())
}
Error: bad read

Caused by:
    0: bad read
    1: timed out waiting on channel

In general, std::error::Error impls are not supposed to duplicate the same content between their Display and source() implementation.