Skip to content

Commit 60a8d74

Browse files
committed
Use color_eyre for handling errors more systematically
1 parent d051f2b commit 60a8d74

File tree

6 files changed

+149
-35
lines changed

6 files changed

+149
-35
lines changed

Cargo.lock

+109
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ regex = "1"
1818
log = "0.4"
1919
simplelog = "0.11"
2020
askama = "0.11"
21+
# Disable support for tracing_error and SpanTrace in eyre
22+
color-eyre = { version = "0.6", default-features = false }
2123

2224

2325
[package.metadata.rpm.cargo]

src/logging.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use color_eyre::eyre::{Context, Result};
12
use simplelog::{ColorChoice, ConfigBuilder, LevelFilter, TermLogger, TerminalMode};
23

34
/// This function initializes the `simplelog` logging system, which plugs into the `log`
45
/// infrastructure. The function returns nothing. It only affects the global state when it runs.
5-
pub fn initialize_logger(verbose: bool, quiet: bool) {
6+
pub fn initialize_logger(verbose: bool, quiet: bool) -> Result<()> {
67
// Set the verbosity level based on the command-line options.
78
// Our `clap` configuration ensures that `verbose` and `quiet` can never be both true.
89
let verbosity = if verbose {
@@ -31,5 +32,7 @@ pub fn initialize_logger(verbose: bool, quiet: bool) {
3132
// Try to use color if possible.
3233
ColorChoice::Auto,
3334
)
34-
.expect("Failed to configure the terminal logging.");
35+
.context("Failed to configure the terminal logging.")?;
36+
37+
Ok(())
3538
}

src/main.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use color_eyre::eyre::Result;
12
use log::{debug, info};
23

34
mod cmd_line;
@@ -20,14 +21,14 @@ pub struct Options {
2021
detect_directory: bool,
2122
}
2223

23-
fn main() {
24+
fn main() -> Result<()> {
2425
// Parse the command-line options
2526
let cmdline_args = cmd_line::get_args();
2627
// Determine the configured verbosity level
2728
let verbose = cmdline_args.is_present("verbose");
2829
let quiet = cmdline_args.is_present("quiet");
2930
// Initialize the logging system based on the set verbosity
30-
logging::initialize_logger(verbose, quiet);
31+
logging::initialize_logger(verbose, quiet)?;
3132

3233
if cmdline_args.is_present("detect-directory") {
3334
info!("The `--detect-directory` (`-D`) option is now enabled by default.");
@@ -74,7 +75,7 @@ fn main() {
7475

7576
// Write all non-populated modules to the disk
7677
for module in &non_populated {
77-
module.write_file(&options);
78+
module.write_file(&options)?;
7879
}
7980

8081
// Treat the populated assembly module as a special case:
@@ -96,15 +97,17 @@ fn main() {
9697
.include(include_statements)
9798
.into();
9899

99-
populated.write_file(&options);
100+
populated.write_file(&options)?;
100101
}
101102

102103
// Validate all file names specified on the command line
103104
if let Some(files_iterator) = cmdline_args.values_of("validate") {
104105
for file in files_iterator {
105-
validation::validate(file);
106+
validation::validate(file)?;
106107
}
107108
}
109+
110+
Ok(())
108111
}
109112

110113
/// Process all titles that have been specified on the command line and that belong to a single

src/validation.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use log::{debug, error};
2-
use regex::{Regex, RegexBuilder};
31
/// This module provides functionality to validate (lint) existing module and assembly files,
42
/// to check if the files meet the template structure and other requirements.
53
use std::fmt;
64
use std::fs;
75
use std::path::Path;
86

7+
use color_eyre::eyre::{Context, Result};
8+
use log::debug;
9+
use regex::{Regex, RegexBuilder};
10+
911
use crate::module::ModuleType;
1012

1113
#[derive(Clone, Copy, Debug)]
@@ -96,20 +98,14 @@ impl fmt::Display for IssueReport {
9698

9799
/// The main validation function. Checks all possible issues in a single file, loaded from a file name.
98100
/// Prints the issues to the standard output.
99-
pub fn validate(file_name: &str) {
101+
pub fn validate(file_name: &str) -> Result<()> {
100102
debug!("Validating file `{}`", file_name);
101103

102104
let path = Path::new(file_name);
103105
let base_name = path.file_name().unwrap().to_str().unwrap();
104106

105-
let read_result = fs::read_to_string(path);
106-
let content = match read_result {
107-
Ok(content) => content,
108-
Err(err) => {
109-
error!("Error reading file `{}`: {}", file_name, err);
110-
return;
111-
}
112-
};
107+
let content =
108+
fs::read_to_string(path).context(format!("Error reading file `{}`.", file_name))?;
113109

114110
let mod_type = determine_mod_type(base_name, &content);
115111

@@ -127,6 +123,8 @@ pub fn validate(file_name: &str) {
127123
};
128124

129125
report_issues(reports, file_name);
126+
127+
Ok(())
130128
}
131129

132130
/// Print a sorted, human-readable report about the issues found in the file

src/write.rs

+16-17
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use std::fs;
22
use std::io;
33
use std::path::PathBuf;
44

5-
use log::{debug, error, info, warn};
5+
use color_eyre::eyre::{Context, Result};
6+
use log::{debug, info, warn};
67

78
use crate::module::Module;
89
use crate::Options;
910

1011
impl Module {
1112
/// Write the generated module content to the path specified in `options` with the set file name.
12-
pub fn write_file(&self, options: &Options) {
13+
pub fn write_file(&self, options: &Options) -> Result<()> {
1314
// Compose the full (but still relative) file path from the target directory and the file name
1415
let full_path_buf: PathBuf = [&options.target_dir, &self.file_name].iter().collect();
1516
let full_path = full_path_buf.as_path();
@@ -26,7 +27,7 @@ impl Module {
2627

2728
io::stdin()
2829
.read_line(&mut answer)
29-
.expect("Failed to read your response");
30+
.context("Failed to read your response")?;
3031

3132
match answer.trim().to_lowercase().as_str() {
3233
"y" | "yes" => {
@@ -36,24 +37,22 @@ impl Module {
3637
info!("→ Preserving the existing file.");
3738
// Break from generating this particular module.
3839
// Other modules that might be in the queue will be generated on next iteration.
39-
return;
40+
return Ok(());
4041
}
4142
};
4243
}
4344

4445
// If the target file doesn't exist, try to write to it
45-
let result = fs::write(full_path, &self.text);
46-
match result {
47-
// If the write succeeds, print the include statement
48-
Ok(()) => {
49-
debug!("Successfully written file `{}`", &full_path.display());
50-
info!("‣ File generated: {}", full_path.display());
51-
info!(" {}", self.include_statement);
52-
}
53-
// If the write fails, print why it failed
54-
Err(e) => {
55-
error!("Failed to write the `{}` file: {}", &full_path.display(), e);
56-
}
57-
}
46+
fs::write(full_path, &self.text).context(format!(
47+
"Failed to write the `{}` file.",
48+
&full_path.display()
49+
))?;
50+
51+
// If the write succeeds, print the include statement
52+
debug!("Successfully written file `{}`", &full_path.display());
53+
info!("‣ File generated: {}", full_path.display());
54+
info!(" {}", self.include_statement);
55+
56+
Ok(())
5857
}
5958
}

0 commit comments

Comments
 (0)