Mercurial > lbo > hg > leveldb-rs
changeset 310:cec9661bb363
disk_env: Return better errors.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 28 Sep 2017 20:43:33 +0200 |
parents | 9a2f35bb13d6 |
children | dbecbde2d8a2 |
files | src/disk_env.rs |
diffstat | 1 files changed, 32 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/disk_env.rs Thu Sep 28 20:43:25 2017 +0200 +++ b/src/disk_env.rs Thu Sep 28 20:43:33 2017 +0200 @@ -1,10 +1,10 @@ -use env::{Env, FileLock, Logger, RandomAccess}; +use env::{path_to_str, Env, FileLock, Logger, RandomAccess}; use env_common::{micros, sleep_for}; use error::{err, Status, StatusCode, Result}; use std::collections::HashMap; use std::fs; -use std::io::{Read, Write}; +use std::io::{self, Read, Write}; use std::iter::FromIterator; use std::mem; use std::os::unix::io::IntoRawFd; @@ -30,11 +30,20 @@ } } +/// map_err_with_name annotates an io::Error with information about the operation and the file. +fn map_err_with_name(method: &'static str, f: &Path, e: io::Error) -> Status { + let mut s = Status::from(e); + s.err = format!("{}: {}: {}", method, s.err, path_to_str(f)); + s +} + // Note: We're using Ok(f()?) in several locations below in order to benefit from the automatic // error conversion using std::convert::From. impl Env for PosixDiskEnv { fn open_sequential_file(&self, p: &Path) -> Result<Box<Read>> { - Ok(Box::new(try!(fs::OpenOptions::new().read(true).open(p)))) + Ok(Box::new(fs::OpenOptions::new().read(true) + .open(p) + .map_err(|e| map_err_with_name("open (seq)", p, e))?)) } fn open_random_access_file(&self, p: &Path) -> Result<Box<RandomAccess>> { Ok(fs::OpenOptions::new().read(true) @@ -42,28 +51,29 @@ .map(|f| { let b: Box<RandomAccess> = Box::new(f); b - })?) + }) + .map_err(|e| map_err_with_name("open (randomaccess)", p, e))?) } fn open_writable_file(&self, p: &Path) -> Result<Box<Write>> { - Ok(Box::new(try!(fs::OpenOptions::new() - .create(true) + Ok(Box::new(fs::OpenOptions::new().create(true) .write(true) .append(false) - .open(p)))) + .open(p) + .map_err(|e| map_err_with_name("open (write)", p, e))?)) } fn open_appendable_file(&self, p: &Path) -> Result<Box<Write>> { - Ok(Box::new(try!(fs::OpenOptions::new() - .create(true) + Ok(Box::new(fs::OpenOptions::new().create(true) .write(true) .append(true) - .open(p)))) + .open(p) + .map_err(|e| map_err_with_name("open (append)", p, e))?)) } fn exists(&self, p: &Path) -> Result<bool> { Ok(p.exists()) } fn children(&self, p: &Path) -> Result<Vec<String>> { - let dir_reader = try!(fs::read_dir(p)); + let dir_reader = fs::read_dir(p).map_err(|e| map_err_with_name("children", p, e))?; let filenames = dir_reader.map(|r| { if !r.is_ok() { "".to_string() @@ -76,21 +86,21 @@ Ok(Vec::from_iter(filenames)) } fn size_of(&self, p: &Path) -> Result<usize> { - let meta = try!(fs::metadata(p)); + let meta = fs::metadata(p).map_err(|e| map_err_with_name("size_of", p, e))?; Ok(meta.len() as usize) } fn delete(&self, p: &Path) -> Result<()> { - Ok(fs::remove_file(p)?) + Ok(fs::remove_file(p).map_err(|e| map_err_with_name("delete", p, e))?) } fn mkdir(&self, p: &Path) -> Result<()> { - Ok(fs::create_dir(p)?) + Ok(fs::create_dir(p).map_err(|e| map_err_with_name("mkdir", p, e))?) } fn rmdir(&self, p: &Path) -> Result<()> { - Ok(fs::remove_dir_all(p)?) + Ok(fs::remove_dir_all(p).map_err(|e| map_err_with_name("rmdir", p, e))?) } fn rename(&self, old: &Path, new: &Path) -> Result<()> { - Ok(fs::rename(old, new)?) + Ok(fs::rename(old, new).map_err(|e| map_err_with_name("rename", old, e))?) } fn lock(&self, p: &Path) -> Result<FileLock> { @@ -99,7 +109,10 @@ if locks.contains_key(&p.to_str().unwrap().to_string()) { Err(Status::new(StatusCode::AlreadyExists, "Lock is held")) } else { - let f = try!(fs::OpenOptions::new().write(true).create(true).open(p)); + let f = fs::OpenOptions::new().write(true) + .create(true) + .open(p) + .map_err(|e| map_err_with_name("lock", p, e))?; let flock_arg = libc::flock { l_type: F_WRLCK, @@ -129,7 +142,7 @@ if !locks.contains_key(&l.id) { return err(StatusCode::LockError, - "unlocking a file that is not locked!"); + &format!("unlocking a file that is not locked: {}", l.id)); } else { let fd = locks.remove(&l.id).unwrap(); let flock_arg = libc::flock { @@ -145,7 +158,7 @@ mem::transmute::<&libc::flock, *const libc::flock>(&&flock_arg)) }; if result < 0 { - return err(StatusCode::LockError, "unlock failed"); + return err(StatusCode::LockError, &format!("unlock failed: {}", l.id)); } Ok(()) }