Merge pull request #551 from killercup/feature/verbose-errors

verbose errors feature
pull/567/head
Yoshua Wuyts 5 years ago committed by GitHub
commit 3f8ec5a007
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,6 +9,7 @@ use std::sync::{Arc, Mutex};
use crate::fs::{Metadata, Permissions};
use crate::future;
use crate::utils::Context as _;
use crate::io::{self, Read, Seek, SeekFrom, Write};
use crate::path::Path;
use crate::prelude::*;
@ -112,7 +113,11 @@ impl File {
/// ```
pub async fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
let path = path.as_ref().to_owned();
let file = spawn_blocking(move || std::fs::File::open(&path)).await?;
let file = spawn_blocking(move || {
std::fs::File::open(&path)
.context(|| format!("Could not open {}", path.display()))
})
.await?;
Ok(File::new(file, true))
}
@ -147,7 +152,11 @@ impl File {
/// ```
pub async fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
let path = path.as_ref().to_owned();
let file = spawn_blocking(move || std::fs::File::create(&path)).await?;
let file = spawn_blocking(move || {
std::fs::File::create(&path)
.context(|| format!("Could not create {}", path.display()))
})
.await?;
Ok(File::new(file, true))
}

@ -291,6 +291,7 @@ cfg_std! {
pub(crate) mod read;
pub(crate) mod seek;
pub(crate) mod write;
pub(crate) mod utils;
mod buf_reader;
mod buf_writer;

@ -0,0 +1,46 @@
use crate::utils::Context;
/// Wrap `std::io::Error` with additional message
///
/// Keeps the original error kind and stores the original I/O error as `source`.
impl<T> Context for Result<T, std::io::Error> {
fn context(self, message: impl Fn() -> String) -> Self {
self.map_err(|e| VerboseError::wrap(e, message()))
}
}
use std::{error::Error as StdError, fmt, io};
#[derive(Debug)]
pub(crate) struct VerboseError {
source: io::Error,
message: String,
}
impl VerboseError {
pub(crate) fn wrap(source: io::Error, message: impl Into<String>) -> io::Error {
io::Error::new(
source.kind(),
VerboseError {
source,
message: message.into(),
},
)
}
}
impl fmt::Display for VerboseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl StdError for VerboseError {
fn description(&self) -> &str {
self.source.description()
}
fn source(&self) -> Option<&(dyn StdError + 'static)> {
Some(&self.source)
}
}

@ -52,6 +52,11 @@ pub fn random(n: u32) -> u32 {
})
}
/// Add additional context to errors
pub(crate) trait Context {
fn context(self, message: impl Fn() -> String) -> Self;
}
/// Defers evaluation of a block of code until the end of the scope.
#[cfg(feature = "default")]
#[doc(hidden)]

@ -0,0 +1,16 @@
use async_std::{fs, task};
#[test]
fn open_file() {
task::block_on(async {
let non_existing_file = "/ashjudlkahasdasdsikdhajik/asdasdasdasdasdasd/fjuiklashdbflasas";
let res = fs::File::open(non_existing_file).await;
match res {
Ok(_) => panic!("Found file with random name: We live in a simulation"),
Err(e) => assert_eq!(
"Could not open /ashjudlkahasdasdsikdhajik/asdasdasdasdasdasd/fjuiklashdbflasas",
&format!("{}", e)
),
}
})
}
Loading…
Cancel
Save