more specific errors for some IO errors
This commit is contained in:
parent
cd6fc35ce4
commit
9c306d55ce
|
@ -97,7 +97,12 @@ impl Config {
|
||||||
if config_filename.is_file() {
|
if config_filename.is_file() {
|
||||||
Self::read_from_toml(config_filename)
|
Self::read_from_toml(config_filename)
|
||||||
} else {
|
} else {
|
||||||
create_dir_all(project_dirs.config_dir())?;
|
let config_dir = project_dirs.config_dir();
|
||||||
|
|
||||||
|
create_dir_all(config_dir).map_err(|e| CouldntCreateConfigDir {
|
||||||
|
path: config_dir.to_owned(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
Self::create_and_return_config(project_dirs.config_dir(), &config_filename)
|
Self::create_and_return_config(project_dirs.config_dir(), &config_filename)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,8 +165,15 @@ impl Config {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut config_file = File::create(config_filename)?;
|
let mut config_file = File::create(config_filename).map_err(|e| CouldntEditConfigFile {
|
||||||
config_file.write_all(to_string(&config).unwrap().as_bytes())?;
|
path: config_filename.to_owned(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
config_file.write_all(to_string(&config).unwrap().as_bytes()).map_err(|e| CouldntEditConfigFile {
|
||||||
|
path: config_filename.to_owned(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,19 @@ use std::io::Read;
|
||||||
|
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error::*, Result};
|
||||||
|
|
||||||
pub fn get_string(note_editor: Option<&String>) -> Result<String> {
|
pub fn get_string(note_editor: Option<&String>) -> Result<String> {
|
||||||
let note_editor = if let Some(note_editor) = note_editor {
|
let note_editor = if let Some(note_editor) = note_editor {
|
||||||
note_editor
|
note_editor
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::EditorIsEmpty);
|
return Err(EditorIsEmpty);
|
||||||
};
|
};
|
||||||
let parts: Vec<_> = note_editor.split(" ").filter(|p| p.len() > 0).collect();
|
let parts: Vec<_> = note_editor.split(" ").filter(|p| p.len() > 0).collect();
|
||||||
let editor = if let Some(name) = parts.get(0) {
|
let editor = if let Some(name) = parts.get(0) {
|
||||||
name.to_owned()
|
name.to_owned()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::EditorIsEmpty);
|
return Err(EditorIsEmpty);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut c = Command::new(editor);
|
let mut c = Command::new(editor);
|
||||||
|
@ -26,7 +26,7 @@ pub fn get_string(note_editor: Option<&String>) -> Result<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tmpfile = NamedTempFile::new()?;
|
let mut tmpfile = NamedTempFile::new().map_err(|e| NoTmpFile(e.to_string()))?;
|
||||||
|
|
||||||
c.arg(tmpfile.as_ref());
|
c.arg(tmpfile.as_ref());
|
||||||
|
|
||||||
|
@ -34,16 +34,19 @@ pub fn get_string(note_editor: Option<&String>) -> Result<String> {
|
||||||
.stdin(Stdio::inherit())
|
.stdin(Stdio::inherit())
|
||||||
.stdout(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
.output()?
|
.output().map_err(|e| EditorFailed {
|
||||||
|
editor: note_editor.clone(),
|
||||||
|
error: e.to_string(),
|
||||||
|
})?
|
||||||
.status;
|
.status;
|
||||||
|
|
||||||
if status.success() {
|
if status.success() {
|
||||||
let mut note = String::new();
|
let mut note = String::new();
|
||||||
|
|
||||||
tmpfile.read_to_string(&mut note)?;
|
tmpfile.read_to_string(&mut note).map_err(|e| CouldntReadTmpFile(e.to_string()))?;
|
||||||
|
|
||||||
Ok(note)
|
Ok(note)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::EditorFailed { editor: note_editor.clone(), error: status.to_string() })
|
Err(EditorFailed { editor: note_editor.clone(), error: status.to_string() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
src/error.rs
40
src/error.rs
|
@ -108,7 +108,45 @@ t config --help for more options.")]
|
||||||
EditorFailed {
|
EditorFailed {
|
||||||
editor: String,
|
editor: String,
|
||||||
error: String,
|
error: String,
|
||||||
}
|
},
|
||||||
|
|
||||||
|
#[error("A temporary file couldn't be created for you to edit. This is very
|
||||||
|
weird, but might have something to do with yout OS.
|
||||||
|
|
||||||
|
Here's the underlaying error:
|
||||||
|
{0}
|
||||||
|
|
||||||
|
If you think this is an issue with this program report it at:
|
||||||
|
|
||||||
|
https://gitlab.com/categulario/tiempo")]
|
||||||
|
NoTmpFile(String),
|
||||||
|
|
||||||
|
#[error("The temporary file you just created couldn't be read. This is the
|
||||||
|
underlaying error:
|
||||||
|
|
||||||
|
{0}
|
||||||
|
|
||||||
|
I didn't imagine this could ever happen, but now I'm curious. Do you mind
|
||||||
|
reporging the issue at https://gitlab.com/categulario/tiempo ?")]
|
||||||
|
CouldntReadTmpFile(String),
|
||||||
|
|
||||||
|
#[error("The ")]
|
||||||
|
CouldntCreateConfigDir {
|
||||||
|
path: PathBuf,
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("A problem ocurred while trying to edit/create the config file at
|
||||||
|
|
||||||
|
{path}
|
||||||
|
|
||||||
|
Is there a permissions issue? Here's the underlaying error:
|
||||||
|
|
||||||
|
{error}")]
|
||||||
|
CouldntEditConfigFile {
|
||||||
|
path: PathBuf,
|
||||||
|
error: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::io::Write;
|
||||||
use csv::Writer;
|
use csv::Writer;
|
||||||
use chrono::SecondsFormat;
|
use chrono::SecondsFormat;
|
||||||
|
|
||||||
use crate::error::Result;
|
use crate::error::{Result, Error::*};
|
||||||
use crate::models::Entry;
|
use crate::models::Entry;
|
||||||
|
|
||||||
pub fn print_formatted<W: Write>(entries: Vec<Entry>, out: &mut W, ids: bool) -> Result<()> {
|
pub fn print_formatted<W: Write>(entries: Vec<Entry>, out: &mut W, ids: bool) -> Result<()> {
|
||||||
|
@ -34,9 +34,7 @@ pub fn print_formatted<W: Write>(entries: Vec<Entry>, out: &mut W, ids: bool) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wtr.flush()?;
|
wtr.flush().map_err(|e| IOError(e))
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::io::Write;
|
||||||
use chrono::{DateTime, Utc, Local, LocalResult, TimeZone};
|
use chrono::{DateTime, Utc, Local, LocalResult, TimeZone};
|
||||||
use ansi_term::Color::Yellow;
|
use ansi_term::Color::Yellow;
|
||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error::*, Result};
|
||||||
use crate::models::Entry;
|
use crate::models::Entry;
|
||||||
use crate::database::{Database, DBVersion};
|
use crate::database::{Database, DBVersion};
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ use crate::database::{Database, DBVersion};
|
||||||
/// Used to convert times from the old database version.
|
/// Used to convert times from the old database version.
|
||||||
fn local_to_utc(t: DateTime<Utc>) -> Result<DateTime<Utc>> {
|
fn local_to_utc(t: DateTime<Utc>) -> Result<DateTime<Utc>> {
|
||||||
let local_time = match Local.from_local_datetime(&t.naive_utc()) {
|
let local_time = match Local.from_local_datetime(&t.naive_utc()) {
|
||||||
LocalResult::None => return Err(Error::NoneLocalTime(t.naive_utc().to_string())),
|
LocalResult::None => return Err(NoneLocalTime(t.naive_utc().to_string())),
|
||||||
LocalResult::Single(t) => t,
|
LocalResult::Single(t) => t,
|
||||||
LocalResult::Ambiguous(t1, t2) => return Err(Error::AmbiguousLocalTime {
|
LocalResult::Ambiguous(t1, t2) => return Err(AmbiguousLocalTime {
|
||||||
orig: t.naive_utc().to_string(),
|
orig: t.naive_utc().to_string(),
|
||||||
t1: t1.naive_local(),
|
t1: t1.naive_local(),
|
||||||
t2: t2.naive_local(),
|
t2: t2.naive_local(),
|
||||||
|
@ -77,7 +77,7 @@ pub fn warn_if_needed<E: Write>(err: &mut E, needs_warning: bool) -> Result<()>
|
||||||
"{} You are using the old timetrap format, it is advised that \
|
"{} You are using the old timetrap format, it is advised that \
|
||||||
you update your database using t migrate",
|
you update your database using t migrate",
|
||||||
Yellow.bold().paint("[WARNING]"),
|
Yellow.bold().paint("[WARNING]"),
|
||||||
)?;
|
).map_err(|e| IOError(e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue