feat: improve error messages
This commit is contained in:
@@ -148,7 +148,7 @@ pub fn config() -> Result<Config> {
|
||||
.subcommand(SubCommand::with_name("init").about("writes an example config"))
|
||||
.get_matches();
|
||||
|
||||
let current_dir = std::env::current_dir().context("could not get current directory")?;
|
||||
let current_dir = std::env::current_dir().context("Could not get current directory")?;
|
||||
|
||||
let config_path = arg_matches.value_of_os("config");
|
||||
let force_load = config_path.is_some();
|
||||
@@ -163,17 +163,17 @@ pub fn config() -> Result<Config> {
|
||||
.create_new(true)
|
||||
.open(&config_path)
|
||||
.and_then(|mut f| f.write_all(std::include_bytes!("../example.audio-conv.yaml")))
|
||||
.with_context(|| format!("unable to write config file to {}", config_path.display()))?;
|
||||
.with_context(|| format!("Unable to write config file to {}", config_path.display()))?;
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
let config_dir = config_path
|
||||
.parent()
|
||||
.context("could not get parent directory of the config file")?;
|
||||
.context("Could not get parent directory of the config file")?;
|
||||
|
||||
let config_file = load_config_file(&config_path)
|
||||
.with_context(|| format!("failed loading config file \"{}\"", config_path.display()))?;
|
||||
.with_context(|| format!("Failed loading config file {}", config_path.display()))?;
|
||||
|
||||
if force_load && config_file.is_none() {
|
||||
return Err(Error::msg(format!(
|
||||
@@ -185,7 +185,7 @@ pub fn config() -> Result<Config> {
|
||||
let default_regex = RegexBuilder::new("\\.(flac|wav)$")
|
||||
.case_insensitive(true)
|
||||
.build()
|
||||
.expect("failed compiling default match regex");
|
||||
.expect("Failed compiling default match regex");
|
||||
|
||||
let transcode_matches = config_file
|
||||
.as_ref()
|
||||
@@ -198,8 +198,8 @@ pub fn config() -> Result<Config> {
|
||||
let glob = GlobBuilder::new(glob)
|
||||
.case_insensitive(true)
|
||||
.build()
|
||||
.context("failed building glob")?;
|
||||
let regex = Regex::new(glob.regex()).context("failed compiling regex")?;
|
||||
.context("Failed building glob")?;
|
||||
let regex = Regex::new(glob.regex()).context("Failed compiling regex")?;
|
||||
Ok(regex)
|
||||
});
|
||||
|
||||
@@ -207,7 +207,7 @@ pub fn config() -> Result<Config> {
|
||||
let regex = RegexBuilder::new(regex)
|
||||
.case_insensitive(true)
|
||||
.build()
|
||||
.context("failed compiling regex")?;
|
||||
.context("Failed compiling regex")?;
|
||||
Ok(regex)
|
||||
});
|
||||
|
||||
@@ -219,7 +219,7 @@ pub fn config() -> Result<Config> {
|
||||
let regex = RegexBuilder::new(&ext)
|
||||
.case_insensitive(true)
|
||||
.build()
|
||||
.context("failed compiling regex")?;
|
||||
.context("Failed compiling regex")?;
|
||||
Ok(regex)
|
||||
});
|
||||
|
||||
@@ -262,7 +262,7 @@ pub fn config() -> Result<Config> {
|
||||
})
|
||||
.ok_or_else(|| Error::msg("\"from\" not configured"))?
|
||||
.canonicalize()
|
||||
.context("could not canonicalize \"from\" path")?
|
||||
.context("Could not canonicalize \"from\" path")?
|
||||
},
|
||||
to: arg_matches
|
||||
.value_of_os("to")
|
||||
@@ -276,7 +276,7 @@ pub fn config() -> Result<Config> {
|
||||
})
|
||||
.ok_or_else(|| Error::msg("\"to\" not configured"))?
|
||||
.canonicalize()
|
||||
.context("could not canonicalize \"to\" path")?,
|
||||
.context("Could not canonicalize \"to\" path")?,
|
||||
matches: transcode_matches,
|
||||
})
|
||||
}
|
||||
@@ -288,6 +288,6 @@ fn load_config_file(path: &Path) -> Result<Option<ConfigFile>> {
|
||||
Err(err) => return Err(Error::new(err)),
|
||||
};
|
||||
let config: ConfigFile =
|
||||
serde_yaml::from_reader(&mut file).context("could not parse config file")?;
|
||||
serde_yaml::from_reader(&mut file).context("Could not parse config file")?;
|
||||
Ok(Some(config))
|
||||
}
|
||||
|
||||
62
src/main.rs
62
src/main.rs
@@ -52,12 +52,12 @@ struct GErrorMessage {
|
||||
|
||||
fn gmake<T: IsA<Element>>(factory_name: &str) -> Result<T> {
|
||||
let res = gstreamer::ElementFactory::make(factory_name, None)
|
||||
.with_context(|| format!("could not make gstreamer Element \"{}\"", factory_name))?
|
||||
.with_context(|| format!("Could not make gstreamer Element \"{}\"", factory_name))?
|
||||
.downcast()
|
||||
.ok()
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"could not cast gstreamer Element \"{}\" into `{}`",
|
||||
"Could not cast gstreamer Element \"{}\" into `{}`",
|
||||
factory_name,
|
||||
std::any::type_name::<T>()
|
||||
)
|
||||
@@ -97,7 +97,7 @@ fn get_conversion_args(config: &Config) -> impl Iterator<Item = Result<Conversio
|
||||
|
||||
let rel_path = e.path().strip_prefix(&config.from).with_context(|| {
|
||||
format!(
|
||||
"unable to get relative path for {} from {}",
|
||||
"Unable to get relative path for {} from {}",
|
||||
e.path().display(),
|
||||
config.from.display()
|
||||
)
|
||||
@@ -112,7 +112,10 @@ fn get_conversion_args(config: &Config) -> impl Iterator<Item = Result<Conversio
|
||||
.map_err(Error::new)
|
||||
.and_then(|md| md.modified().map_err(Error::new))
|
||||
.with_context(|| {
|
||||
format!("unable to get mtime for from file {}", e.path().display())
|
||||
format!(
|
||||
"Unable to get mtime for \"from\" file {}",
|
||||
e.path().display()
|
||||
)
|
||||
})?;
|
||||
let to_mtime = to.metadata().and_then(|md| md.modified());
|
||||
match to_mtime {
|
||||
@@ -120,7 +123,7 @@ fn get_conversion_args(config: &Config) -> impl Iterator<Item = Result<Conversio
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => true,
|
||||
Err(err) => {
|
||||
return Err(err).with_context(|| {
|
||||
format!("unable to get mtime for to file {}", to.display())
|
||||
format!("Unable to get mtime for \"to\" file {}", to.display())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -147,15 +150,15 @@ async fn main() -> Result<()> {
|
||||
let main_handle = async move {
|
||||
let ok = task::spawn_local(main_loop(ui_queue))
|
||||
.await
|
||||
.context("main task failed")??;
|
||||
.context("Main task failed")??;
|
||||
Result::<_>::Ok(ok)
|
||||
};
|
||||
|
||||
let ui_handle = async move {
|
||||
let ok = task::spawn_local(ui_fut)
|
||||
.await
|
||||
.context("ui task failed")?
|
||||
.context("ui failed")?;
|
||||
.context("Ui task failed")?
|
||||
.context("Ui failed")?;
|
||||
Result::<_>::Ok(ok)
|
||||
};
|
||||
|
||||
@@ -168,20 +171,20 @@ async fn main() -> Result<()> {
|
||||
async fn main_loop(ui_queue: ui::MsgQueue) -> Result<()> {
|
||||
let (config, conv_args) = task::spawn_blocking(|| -> Result<_> {
|
||||
gstreamer::init()?;
|
||||
let config = config::config().context("could not get the config")?;
|
||||
let config = config::config().context("Could not get the config")?;
|
||||
|
||||
let conv_args = get_conversion_args(&config)
|
||||
.collect::<Result<Vec<_>>>()
|
||||
.context("failed loading dir structure")?;
|
||||
.context("Failed loading dir structure")?;
|
||||
|
||||
Ok((config, conv_args))
|
||||
})
|
||||
.await
|
||||
.context("init task failed")??;
|
||||
.context("Init task failed")??;
|
||||
|
||||
let log_path = Path::new(".")
|
||||
.canonicalize()
|
||||
.context("unable to canonicalize path to log file")?
|
||||
.context("Unable to canonicalize path to log file")?
|
||||
.join("audio-conv.log");
|
||||
|
||||
ui_queue.push(ui::Msg::Init {
|
||||
@@ -206,7 +209,7 @@ async fn main_loop(ui_queue: ui::MsgQueue) -> Result<()> {
|
||||
Ok(()) => ui_queue.push(ui::Msg::TaskEnd { id: i }),
|
||||
Err(err) => {
|
||||
let err = err.context(format!(
|
||||
"failed transcoding \"{}\"",
|
||||
"Transcoding failed for {}",
|
||||
args.rel_from_path.display()
|
||||
));
|
||||
|
||||
@@ -268,7 +271,7 @@ async fn transcode(
|
||||
fs::create_dir_all(
|
||||
to_path
|
||||
.parent()
|
||||
.with_context(|| format!("could not get parent dir for {}", to_path.display()))?,
|
||||
.with_context(|| format!("Could not get parent dir for {}", to_path.display()))?,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -281,7 +284,7 @@ async fn transcode(
|
||||
Transcode::Copy => {
|
||||
fs::copy(&from_path, &to_path_tmp).await.with_context(|| {
|
||||
format!(
|
||||
"could not copy file from {} to {}",
|
||||
"Could not copy file from {} to {}",
|
||||
from_path.display(),
|
||||
to_path_tmp.display()
|
||||
)
|
||||
@@ -303,7 +306,7 @@ async fn transcode(
|
||||
|
||||
fs::rename(&to_path_tmp, &to_path).await.with_context(|| {
|
||||
format!(
|
||||
"could not rename temporary file {} to {}",
|
||||
"Could not rename temporary file {} to {}",
|
||||
to_path_tmp.display(),
|
||||
to_path.display()
|
||||
)
|
||||
@@ -385,7 +388,7 @@ async fn transcode_gstreamer(
|
||||
"bitrate",
|
||||
&i32::from(*bitrate)
|
||||
.checked_mul(1_000)
|
||||
.context("bitrate overflowed")?,
|
||||
.context("Bitrate overflowed")?,
|
||||
)?;
|
||||
encoder.set_property_from_str(
|
||||
"bitrate-type",
|
||||
@@ -468,7 +471,9 @@ async fn transcode_gstreamer(
|
||||
}
|
||||
});
|
||||
|
||||
let bus = pipeline.get_bus().context("pipe get bus")?;
|
||||
let bus = pipeline
|
||||
.get_bus()
|
||||
.context("Could not get bus for pipeline")?;
|
||||
|
||||
pipeline
|
||||
.set_state(gstreamer::State::Playing)
|
||||
@@ -489,11 +494,9 @@ async fn transcode_gstreamer(
|
||||
Ok(false)
|
||||
}
|
||||
MessageView::Error(err) => {
|
||||
pipeline.set_state(gstreamer::State::Null).context(
|
||||
"Unable to set the pipeline to the `Null` state, after error",
|
||||
)?;
|
||||
let pipe_stop_res = pipeline.set_state(gstreamer::State::Null);
|
||||
|
||||
let err = err
|
||||
let err: Error = err
|
||||
.get_details()
|
||||
.and_then(|details| {
|
||||
if details.get_name() != "error-details" {
|
||||
@@ -519,7 +522,15 @@ async fn transcode_gstreamer(
|
||||
}
|
||||
.into()
|
||||
});
|
||||
Err(err)
|
||||
|
||||
if let Err(pipe_err) = pipe_stop_res {
|
||||
let err = err.context(pipe_err).context(
|
||||
"Unable to set the pipeline to the `Null` state, after error",
|
||||
);
|
||||
Err(err)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
_ => Ok(true),
|
||||
}
|
||||
@@ -532,8 +543,7 @@ async fn transcode_gstreamer(
|
||||
}
|
||||
})
|
||||
.try_for_each(|_| futures::future::ready(Ok(())))
|
||||
.await
|
||||
.context("failed converting")?;
|
||||
.await?;
|
||||
|
||||
Result::<_>::Ok(())
|
||||
};
|
||||
@@ -597,7 +607,7 @@ where
|
||||
Err(fs_err) => {
|
||||
let err = err
|
||||
.context(fs_err)
|
||||
.context(format!("removing {} failed", path.display()));
|
||||
.context(format!("Removing file {} failed", path.display()));
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
|
||||
12
src/ui.rs
12
src/ui.rs
@@ -88,7 +88,7 @@ impl State {
|
||||
Msg::TaskEnd { id } => {
|
||||
self.running_tasks
|
||||
.remove(&id)
|
||||
.context("unable to remove finished task; could't find task")?;
|
||||
.context("Unable to remove finished task; could't find task")?;
|
||||
self.ended_tasks += 1;
|
||||
}
|
||||
Msg::TaskProgress { id, ratio } => {
|
||||
@@ -102,7 +102,7 @@ impl State {
|
||||
// TODO
|
||||
self.running_tasks
|
||||
.remove(&id)
|
||||
.context("unable to remove errored task; could't find task")?;
|
||||
.context("Unable to remove errored task; could't find task")?;
|
||||
self.ended_tasks += 1;
|
||||
self.has_errored = true;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ impl State {
|
||||
running_tasks.sort_by_key(|task| task.id);
|
||||
|
||||
if !self.has_rendered {
|
||||
self.terminal.clear().context("cleaning ui failed")?;
|
||||
self.terminal.clear().context("Clearing ui failed")?;
|
||||
self.has_rendered = true;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ impl State {
|
||||
chunks[1],
|
||||
);
|
||||
})
|
||||
.context("rendering ui failed")?;
|
||||
.context("Rendering ui failed")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -267,8 +267,8 @@ pub fn init() -> (MsgQueue, impl Future<Output = Result<()>>) {
|
||||
}
|
||||
})
|
||||
.await
|
||||
.context("ui update task failed")?
|
||||
.context("ui update failed")?;
|
||||
.context("Ui update task failed")?
|
||||
.context("Ui update failed")?;
|
||||
|
||||
match render_res {
|
||||
Some(s) => wrapped = Some(s),
|
||||
|
||||
Reference in New Issue
Block a user