diff --git a/.cargo-husky/hooks/pre-push b/.cargo-husky/hooks/pre-push
new file mode 100755
index 00000000..46fb32d2
--- /dev/null
+++ b/.cargo-husky/hooks/pre-push
@@ -0,0 +1,2 @@
+echo "Running pre-push hook: cargo +nightly clippy -- -D clippy::all"
+cargo +nightly clippy -- -D clippy::all
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index d3f49cfa..b5030dc0 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -38,6 +38,7 @@
         "curr",
         "czvf",
         "fpath",
+        "fract",
         "gotop",
         "gtop",
         "haase",
diff --git a/Cargo.lock b/Cargo.lock
index 9c458943..20f2221f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -27,6 +27,12 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "anyhow"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
+
 [[package]]
 name = "arc-swap"
 version = "0.4.6"
@@ -131,6 +137,7 @@ dependencies = [
 name = "bottom"
 version = "0.4.7"
 dependencies = [
+ "anyhow",
  "assert_cmd",
  "backtrace",
  "battery",
@@ -151,6 +158,7 @@ dependencies = [
  "regex",
  "serde",
  "sysinfo",
+ "thiserror",
  "toml",
  "tui",
  "typed-builder",
@@ -1273,6 +1281,26 @@ dependencies = [
  "unicode-width",
 ]
 
+[[package]]
+name = "thiserror"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "thread_local"
 version = "1.0.1"
diff --git a/Cargo.toml b/Cargo.toml
index ce60333a..cdac5df4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,14 +24,17 @@ lto = "fat"
 codegen-units = 1
 
 [dependencies]
+anyhow = "1.0.32"
 battery = "0.7.6"
-crossterm = "0.17"
 chrono = "0.4.15"
+crossterm = "0.17"
+ctrlc = {version = "3.1", features = ["termination"]}
 clap = "2.33"
 dirs = "3.0.1"
 futures = "0.3.5"
 heim = "0.0.10"
 itertools = "0.9.0"
+libc = "0.2"
 regex = "1.3"
 sysinfo = "0.15.1"
 toml = "0.5.6"
@@ -41,8 +44,7 @@ backtrace = "0.3"
 serde = {version = "1.0", features = ["derive"] }
 unicode-segmentation = "1.6.0"
 unicode-width = "0.1"
-libc = "0.2"
-ctrlc = {version = "3.1", features = ["termination"]}
+thiserror = "1.0.20"
 tui = {version = "0.9.5", features = ["crossterm"], default-features = false }
 
 # For debugging only...
@@ -82,5 +84,5 @@ output = "bottom_x86_64_installer.msi"
 
 [dev-dependencies.cargo-husky]
 version = "1"
-default-features = false 
-features = ["prepush-hook", "run-cargo-clippy"]
\ No newline at end of file
+default-features = false
+features = ["user-hooks"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 0083f3f7..cbf5b55e 100644
--- a/README.md
+++ b/README.md
@@ -509,7 +509,7 @@ Supported named colours are one of the following strings: `Reset, Black, Red, Gr
 | Cursor colour                   | The cursor's colour                                   | `cursor_color="#ffffff"`                                |
 | Selected text colour            | The colour of text that is selected                   | `scroll_entry_text_color="#ffffff"`                     |
 | Selected text background colour | The background colour of text that is selected        | `scroll_entry_bg_color="#ffffff"`                       |
-| Battery bar colours             | Colour used is based on percentage and no. of colours | `battery_colours=["green", "yellow", "red"]`            |
+| Battery bar colours             | Colour used is based on percentage and no. of colours | `battery_colors=["green", "yellow", "red"]`             |
 
 #### Layout
 
diff --git a/src/app/data_harvester/processes.rs b/src/app/data_harvester/processes.rs
index bdd6a609..dcd6d647 100644
--- a/src/app/data_harvester/processes.rs
+++ b/src/app/data_harvester/processes.rs
@@ -253,11 +253,11 @@ fn read_proc<S: core::hash::BuildHasher>(
         .splitn(2, '(')
         .collect::<Vec<_>>()
         .last()
-        .ok_or(BottomError::MinorError())?
+        .ok_or(BottomError::MinorError)?
         .rsplitn(2, ')')
         .collect::<Vec<_>>()
         .last()
-        .ok_or(BottomError::MinorError())?
+        .ok_or(BottomError::MinorError)?
         .to_string();
     let command = {
         let cmd = read_path_contents(&pid_stat.proc_cmdline_path)?;
@@ -271,7 +271,7 @@ fn read_proc<S: core::hash::BuildHasher>(
         .split(')')
         .collect::<Vec<_>>()
         .last()
-        .ok_or(BottomError::MinorError())?
+        .ok_or(BottomError::MinorError)?
         .split_whitespace()
         .collect::<Vec<&str>>();
     let (process_state_char, process_state) = get_linux_process_state(&stat);
diff --git a/src/app/layout_manager.rs b/src/app/layout_manager.rs
index 35c6e02f..6036c2a5 100644
--- a/src/app/layout_manager.rs
+++ b/src/app/layout_manager.rs
@@ -943,7 +943,25 @@ impl std::str::FromStr for BottomWidgetType {
             "empty" => Ok(BottomWidgetType::Empty),
             "battery" | "batt" => Ok(BottomWidgetType::Battery),
             _ => Err(BottomError::ConfigError(format!(
-                "invalid widget type: {}", // FIXME: Make this more helpful, specify valid widget types (just go through the list)
+                "\"{}\" is an invalid widget name.
+
+Supported widget names:
++--------------------------+
+|            cpu           |
++--------------------------+
+|        mem, memory       |
++--------------------------+
+|       net, network       |
++--------------------------+
+| proc, process, processes |
++--------------------------+
+|     temp, temperature    |
++--------------------------+
+|           disk           |
++--------------------------+
+|       batt, battery      |
++--------------------------+
+                ",
                 s
             ))),
         }
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 95444491..7f8b9900 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -3,7 +3,7 @@
 #[macro_use]
 extern crate log;
 
-use bottom::{canvas, constants::*, data_conversion::*, options::*, utils::error, *};
+use bottom::{canvas, constants::*, data_conversion::*, options::*, *};
 
 use std::{
     boxed::Box,
@@ -17,6 +17,7 @@ use std::{
     time::Duration,
 };
 
+use anyhow::{Context, Result};
 use crossterm::{
     event::EnableMouseCapture,
     execute,
@@ -24,18 +25,22 @@ use crossterm::{
 };
 use tui::{backend::CrosstermBackend, Terminal};
 
-fn main() -> error::Result<()> {
+fn main() -> Result<()> {
     #[cfg(debug_assertions)]
     {
         utils::logging::init_logger()?;
     }
     let matches = clap::get_matches();
 
-    let config: Config = create_config(matches.value_of("CONFIG_LOCATION"))?;
+    let config_path = read_config(matches.value_of("CONFIG_LOCATION"))
+        .context("Unable to access the given config file location.")?;
+    let config: Config = create_or_get_config(&config_path)
+        .context("Unable to properly parse or create the config file.")?;
 
     // Get widget layout separately
     let (widget_layout, default_widget_id, default_widget_type_option) =
-        get_widget_layout(&matches, &config)?;
+        get_widget_layout(&matches, &config)
+            .context("Found an issue while trying to build the widget layout.")?;
 
     // Create "app" struct, which will control most of the program and store settings/state
     let mut app = build_app(
diff --git a/src/canvas/canvas_colours.rs b/src/canvas/canvas_colours.rs
index 86c96f4b..98932d5d 100644
--- a/src/canvas/canvas_colours.rs
+++ b/src/canvas/canvas_colours.rs
@@ -1,5 +1,4 @@
 use tui::style::{Color, Style};
-// use tui::style::Modifier;
 
 use colour_utils::*;
 
@@ -175,11 +174,10 @@ impl CanvasColours {
         Ok(())
     }
 
-    pub fn set_battery_colours(&mut self, colours: &[String]) -> error::Result<()> {
+    pub fn set_battery_colors(&mut self, colours: &[String]) -> error::Result<()> {
         if colours.is_empty() {
             Err(error::BottomError::ConfigError(
-                "invalid colour config: battery colour list must have at least one colour!"
-                    .to_string(),
+                "battery colour list must have at least one colour.".to_string(),
             ))
         } else {
             let generated_colours: Result<Vec<_>, _> = colours
diff --git a/src/canvas/canvas_colours/colour_utils.rs b/src/canvas/canvas_colours/colour_utils.rs
index 8b2f0594..f94b9bd9 100644
--- a/src/canvas/canvas_colours/colour_utils.rs
+++ b/src/canvas/canvas_colours/colour_utils.rs
@@ -100,7 +100,7 @@ pub fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
     fn hex_err(hex: &str) -> error::Result<u8> {
         Err(
             error::BottomError::ConfigError(format!(
-                "invalid color hex: error when parsing hex value {}.  It must be a valid 7 character hex string of the (ie: \"#112233\")."
+                "\"{}\" is an invalid hex colour.  It must be a valid 7 character hex string of the (ie: \"#112233\")."
             , hex))
         )
     }
@@ -124,7 +124,7 @@ pub fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
         }
 
         Err(error::BottomError::ConfigError(format!(
-            "invalid color hex: value {} is not of valid length.  It must be a 7 character string of the form \"#112233\".",
+            "\"{}\" is an invalid hex colour.  It must be a 7 character string of the form \"#112233\".",
             hex
         )))
     }
@@ -144,7 +144,7 @@ pub fn get_style_from_config(input_val: &str) -> error::Result<Style> {
         }
     } else {
         Err(error::BottomError::ConfigError(format!(
-            "invalid color: value {} is not valid.",
+            "value \"{}\" is not valid.",
             input_val
         )))
     }
@@ -161,7 +161,7 @@ pub fn get_colour_from_config(input_val: &str) -> error::Result<Color> {
         }
     } else {
         Err(error::BottomError::ConfigError(format!(
-            "invalid color: value {} is not valid.",
+            "value \"{}\" is not valid.",
             input_val
         )))
     }
@@ -175,7 +175,7 @@ fn convert_rgb_to_color(rgb_str: &str) -> error::Result<Color> {
     let rgb_list = rgb_str.split(',').collect::<Vec<&str>>();
     if rgb_list.len() != 3 {
         return Err(error::BottomError::ConfigError(format!(
-            "invalid RGB color: value {} is not of valid length.  It must be a comma separated value with 3 integers from 0 to 255 (ie: \"255, 0, 155\").",
+            "value \"{}\" is an invalid RGB colour.  It must be a comma separated value with 3 integers from 0 to 255 (ie: \"255, 0, 155\").",
             rgb_str
         )));
     }
@@ -194,7 +194,7 @@ fn convert_rgb_to_color(rgb_str: &str) -> error::Result<Color> {
         Ok(Color::Rgb(rgb[0], rgb[1], rgb[2]))
     } else {
         Err(error::BottomError::ConfigError(format!(
-            "invalid RGB color: value {} contained invalid RGB values.  It must be a comma separated value with 3 integers from 0 to 255 (ie: \"255, 0, 155\").",
+            "value \"{}\" contained invalid RGB values.  It must be a comma separated value with 3 integers from 0 to 255 (ie: \"255, 0, 155\").",
             rgb_str
         )))
     }
@@ -211,9 +211,23 @@ fn convert_name_to_color(color_name: &str) -> error::Result<Color> {
     }
 
     Err(error::BottomError::ConfigError(format!(
-        "invalid named color: value {} is not a supported named colour.  The following are supported strings: \
-		Reset, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, \
-		LightYellow, LightBlue, LightMagenta, LightCyan, White",
+        "\"{}\" is an invalid named colour.
+        
+The following are supported strings: 
++--------+------------+--------------+
+|  Reset | Magenta    | LightYellow  |
++--------+------------+--------------+
+|  Black | Cyan       | LightBlue    |
++--------+------------+--------------+
+|   Red  | Gray       | LightMagenta |
++--------+------------+--------------+
+|  Green | DarkGray   | LightCyan    |
++--------+------------+--------------+
+| Yellow | LightRed   | White        |
++--------+------------+--------------+
+|  Blue  | LightGreen |              |
++--------+------------+--------------+
+        ",
         color_name
     )))
 }
diff --git a/src/clap.rs b/src/clap.rs
index e4bed377..6b63ba42 100644
--- a/src/clap.rs
+++ b/src/clap.rs
@@ -239,7 +239,7 @@ For example, suppose we have a layout that looks like:
 Setting '--default_widget_type Temp' will make the Temperature
 widget selected by default.
 
-Supported widget types:
+Supported widget names:
 +--------------------------+
 |            cpu           |
 +--------------------------+
diff --git a/src/lib.rs b/src/lib.rs
index 4850d48c..207c2963 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,8 +5,10 @@ extern crate log;
 
 use std::{
     boxed::Box,
+    fs,
     io::{stdout, Write},
     panic::PanicInfo,
+    path::PathBuf,
     thread,
     time::{Duration, Instant},
 };
@@ -18,6 +20,8 @@ use crossterm::{
     terminal::{disable_raw_mode, LeaveAlternateScreen},
 };
 
+use anyhow::Context;
+
 use app::{
     data_harvester::{self, processes::ProcessSorting},
     layout_manager::{UsedWidgets, WidgetDirection},
@@ -164,15 +168,14 @@ pub fn handle_key_event_or_break(
     false
 }
 
-pub fn create_config(flag_config_location: Option<&str>) -> error::Result<Config> {
-    use std::{ffi::OsString, fs};
-    let config_path = if let Some(conf_loc) = flag_config_location {
-        Some(OsString::from(conf_loc))
+pub fn read_config(config_location: Option<&str>) -> error::Result<Option<PathBuf>> {
+    let config_path = if let Some(conf_loc) = config_location {
+        Some(PathBuf::from(conf_loc))
     } else if cfg!(target_os = "windows") {
         if let Some(home_path) = dirs::config_dir() {
             let mut path = home_path;
             path.push(DEFAULT_CONFIG_FILE_PATH);
-            Some(path.into_os_string())
+            Some(path)
         } else {
             None
         }
@@ -182,13 +185,13 @@ pub fn create_config(flag_config_location: Option<&str>) -> error::Result<Config
         path.push(DEFAULT_CONFIG_FILE_PATH);
         if path.exists() {
             // If it already exists, use the old one.
-            Some(path.into_os_string())
+            Some(path)
         } else {
             // If it does not, use the new one!
             if let Some(config_path) = dirs::config_dir() {
                 let mut path = config_path;
                 path.push(DEFAULT_CONFIG_FILE_PATH);
-                Some(path.into_os_string())
+                Some(path)
             } else {
                 None
             }
@@ -197,9 +200,11 @@ pub fn create_config(flag_config_location: Option<&str>) -> error::Result<Config
         None
     };
 
-    if let Some(config_path) = config_path {
-        let path = std::path::Path::new(&config_path);
+    Ok(config_path)
+}
 
+pub fn create_or_get_config(config_path: &Option<PathBuf>) -> error::Result<Config> {
+    if let Some(path) = config_path {
         if let Ok(config_string) = fs::read_to_string(path) {
             Ok(toml::from_str(config_string.as_str())?)
         } else {
@@ -229,48 +234,76 @@ pub fn try_drawing(
 
 pub fn generate_config_colours(
     config: &Config, painter: &mut canvas::Painter,
-) -> error::Result<()> {
+) -> anyhow::Result<()> {
     if let Some(colours) = &config.colors {
         if let Some(border_color) = &colours.border_color {
-            painter.colours.set_border_colour(border_color)?;
+            painter
+                .colours
+                .set_border_colour(border_color)
+                .context("Update 'border_color' in your config file..")?;
         }
 
         if let Some(highlighted_border_color) = &colours.highlighted_border_color {
             painter
                 .colours
-                .set_highlighted_border_colour(highlighted_border_color)?;
+                .set_highlighted_border_colour(highlighted_border_color)
+                .context("Update 'highlighted_border_color' in your config file..")?;
         }
 
         if let Some(text_color) = &colours.text_color {
-            painter.colours.set_text_colour(text_color)?;
+            painter
+                .colours
+                .set_text_colour(text_color)
+                .context("Update 'text_color' in your config file..")?;
         }
 
         if let Some(avg_cpu_color) = &colours.avg_cpu_color {
-            painter.colours.set_avg_cpu_colour(avg_cpu_color)?;
+            painter
+                .colours
+                .set_avg_cpu_colour(avg_cpu_color)
+                .context("Update 'avg_cpu_color' in your config file..")?;
         }
 
         if let Some(all_cpu_color) = &colours.all_cpu_color {
-            painter.colours.set_all_cpu_colour(all_cpu_color)?;
+            painter
+                .colours
+                .set_all_cpu_colour(all_cpu_color)
+                .context("Update 'all_cpu_color' in your config file..")?;
         }
 
         if let Some(cpu_core_colors) = &colours.cpu_core_colors {
-            painter.colours.set_cpu_colours(cpu_core_colors)?;
+            painter
+                .colours
+                .set_cpu_colours(cpu_core_colors)
+                .context("Update 'cpu_core_colors' in your config file..")?;
         }
 
         if let Some(ram_color) = &colours.ram_color {
-            painter.colours.set_ram_colour(ram_color)?;
+            painter
+                .colours
+                .set_ram_colour(ram_color)
+                .context("Update 'ram_color' in your config file..")?;
         }
 
         if let Some(swap_color) = &colours.swap_color {
-            painter.colours.set_swap_colour(swap_color)?;
+            painter
+                .colours
+                .set_swap_colour(swap_color)
+                .context("Update 'swap_color' in your config file..")?;
         }
 
         if let Some(rx_color) = &colours.rx_color {
-            painter.colours.set_rx_colour(rx_color)?;
+            painter
+                .colours
+                .set_rx_colour(rx_color)
+                .context("Update 'rx_color' in your config file..")?;
         }
 
         if let Some(tx_color) = &colours.tx_color {
-            painter.colours.set_tx_colour(tx_color)?;
+            painter
+                .colours
+                .set_tx_colour(tx_color)
+                .context("Update 'tx_color' in your config file..")?;
         }
 
         // if let Some(rx_total_color) = &colours.rx_total_color {
@@ -284,33 +317,43 @@ pub fn generate_config_colours(
         if let Some(table_header_color) = &colours.table_header_color {
             painter
                 .colours
-                .set_table_header_colour(table_header_color)?;
+                .set_table_header_colour(table_header_color)
+                .context("Update 'table_header_color' in your config file..")?;
         }
 
         if let Some(scroll_entry_text_color) = &colours.selected_text_color {
             painter
                 .colours
-                .set_scroll_entry_text_color(scroll_entry_text_color)?;
+                .set_scroll_entry_text_color(scroll_entry_text_color)
+                .context("Update 'selected_text_color' in your config file..")?;
         }
 
         if let Some(scroll_entry_bg_color) = &colours.selected_bg_color {
             painter
                 .colours
-                .set_scroll_entry_bg_color(scroll_entry_bg_color)?;
+                .set_scroll_entry_bg_color(scroll_entry_bg_color)
+                .context("Update 'selected_bg_color' in your config file..")?;
         }
 
         if let Some(widget_title_color) = &colours.widget_title_color {
             painter
                 .colours
-                .set_widget_title_colour(widget_title_color)?;
+                .set_widget_title_colour(widget_title_color)
+                .context("Update 'widget_title_color' in your config file..")?;
         }
 
         if let Some(graph_color) = &colours.graph_color {
-            painter.colours.set_graph_colour(graph_color)?;
+            painter
+                .colours
+                .set_graph_colour(graph_color)
+                .context("Update 'graph_color' in your config file..")?;
         }
 
         if let Some(battery_colors) = &colours.battery_colors {
-            painter.colours.set_battery_colours(battery_colors)?;
+            painter
+                .colours
+                .set_battery_colors(battery_colors)
+                .context("Update 'battery_colors' in your config file.")?;
         }
     }
 
diff --git a/src/options.rs b/src/options.rs
index 41059f9c..c2e33993 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -12,6 +12,8 @@ use layout_options::*;
 
 pub mod layout_options;
 
+use anyhow::{Context, Result};
+
 #[derive(Default, Deserialize)]
 pub struct Config {
     pub flags: Option<ConfigFlags>,
@@ -70,10 +72,11 @@ pub struct ConfigColours {
 pub fn build_app(
     matches: &clap::ArgMatches<'static>, config: &Config, widget_layout: &BottomLayout,
     default_widget_id: u64, default_widget_type_option: &Option<BottomWidgetType>,
-) -> error::Result<App> {
+) -> Result<App> {
     use BottomWidgetType::*;
     let autohide_time = get_autohide_time(&matches, &config);
-    let default_time_value = get_default_time_value(&matches, &config)?;
+    let default_time_value = get_default_time_value(&matches, &config)
+        .context("Update 'default_time_value' in your config file.")?;
     let use_basic_mode = get_use_basic_mode(&matches, &config);
 
     // For processes
@@ -213,15 +216,18 @@ pub fn build_app(
     };
 
     let app_config_fields = AppConfigFields {
-        update_rate_in_milliseconds: get_update_rate_in_milliseconds(matches, config)?,
-        temperature_type: get_temperature(matches, config)?,
+        update_rate_in_milliseconds: get_update_rate_in_milliseconds(matches, config)
+            .context("Update 'rate' in your config file.")?,
+        temperature_type: get_temperature(matches, config)
+            .context("Update 'temperature_type' in your config file.")?,
         show_average_cpu: get_show_average_cpu(matches, config),
         use_dot: get_use_dot(matches, config),
         left_legend: get_use_left_legend(matches, config),
         use_current_cpu_total: get_use_current_cpu_total(matches, config),
         use_basic_mode,
         default_time_value,
-        time_interval: get_time_interval(matches, config)?,
+        time_interval: get_time_interval(matches, config)
+            .context("Update 'time_delta' in your config file.")?,
         hide_time: get_hide_time(matches, config),
         autohide_time,
         use_old_network_legend: get_use_old_network_legend(matches, config),
@@ -316,7 +322,7 @@ pub fn get_widget_layout(
             ret_bottom_layout
         } else {
             return Err(error::BottomError::ConfigError(
-                "invalid layout config: please have at least one widget.".to_string(),
+                "please have at least one widget under the '[[row]]' section.".to_string(),
             ));
         }
     };
@@ -340,12 +346,12 @@ fn get_update_rate_in_milliseconds(
     };
 
     if update_rate_in_milliseconds < 250 {
-        return Err(BottomError::InvalidArg(
-            "Please set your update rate to be at least 250 milliseconds.".to_string(),
+        return Err(BottomError::ConfigError(
+            "set your update rate to be at least 250 milliseconds.".to_string(),
         ));
     } else if update_rate_in_milliseconds as u128 > std::u64::MAX as u128 {
-        return Err(BottomError::InvalidArg(
-            "Please set your update rate to be at most unsigned INT_MAX.".to_string(),
+        return Err(BottomError::ConfigError(
+            "set your update rate to be at most unsigned INT_MAX.".to_string(),
         ));
     }
 
@@ -368,11 +374,10 @@ fn get_temperature(
                 "fahrenheit" | "f" => Ok(data_harvester::temperature::TemperatureType::Fahrenheit),
                 "kelvin" | "k" => Ok(data_harvester::temperature::TemperatureType::Kelvin),
                 "celsius" | "c" => Ok(data_harvester::temperature::TemperatureType::Celsius),
-                _ => Err(BottomError::ConfigError(
-                    "invalid temperature type: please have the value be of the form \
-						 <kelvin|k|celsius|c|fahrenheit|f>"
-                        .to_string(),
-                )),
+                _ => Err(BottomError::ConfigError(format!(
+                    "\"{}\" is an invalid temperature type, use \"<kelvin|k|celsius|c|fahrenheit|f>\".",
+                    temp_type
+                ))),
             };
         }
     }
@@ -455,12 +460,12 @@ fn get_default_time_value(
     };
 
     if default_time < 30000 {
-        return Err(BottomError::InvalidArg(
-            "Please set your default value to be at least 30000 milliseconds.".to_string(),
+        return Err(BottomError::ConfigError(
+            "set your default value to be at least 30000 milliseconds.".to_string(),
         ));
     } else if default_time as u128 > STALE_MAX_MILLISECONDS as u128 {
-        return Err(BottomError::InvalidArg(format!(
-            "Please set your default value to be at most {} milliseconds.",
+        return Err(BottomError::ConfigError(format!(
+            "set your default value to be at most {} milliseconds.",
             STALE_MAX_MILLISECONDS
         )));
     }
@@ -482,12 +487,12 @@ fn get_time_interval(matches: &clap::ArgMatches<'static>, config: &Config) -> er
     };
 
     if time_interval < 1000 {
-        return Err(BottomError::InvalidArg(
-            "Please set your time delta to be at least 1000 milliseconds.".to_string(),
+        return Err(BottomError::ConfigError(
+            "set your time delta to be at least 1000 milliseconds.".to_string(),
         ));
     } else if time_interval > STALE_MAX_MILLISECONDS as u128 {
-        return Err(BottomError::InvalidArg(format!(
-            "Please set your time delta to be at most {} milliseconds.",
+        return Err(BottomError::ConfigError(format!(
+            "set your time delta to be at most {} milliseconds.",
             STALE_MAX_MILLISECONDS
         )));
     }
@@ -601,8 +606,8 @@ fn get_default_widget_and_count(
         };
 
         if widget_count > std::u64::MAX as u128 {
-            Err(BottomError::InvalidArg(
-                "Please set your widget count to be at most unsigned INT_MAX.".to_string(),
+            Err(BottomError::ConfigError(
+                "set your widget count to be at most unsigned INT_MAX.".to_string(),
             ))
         } else {
             Ok((widget_type, widget_count as u64))
diff --git a/src/utils/error.rs b/src/utils/error.rs
index 4c607ebe..1cb17595 100644
--- a/src/utils/error.rs
+++ b/src/utils/error.rs
@@ -1,60 +1,39 @@
 use std::{borrow::Cow, result};
+use thiserror::Error;
 
 /// A type alias for handling errors related to Bottom.
 pub type Result<T> = result::Result<T, BottomError>;
 
 /// An error that can occur while Bottom runs.
-#[derive(Debug)]
+#[derive(Debug, Error)]
 pub enum BottomError {
     /// An error when there is an IO exception.
+    #[error("IO exception, {0}")]
     InvalidIO(String),
-    /// An error when there is an invalid argument passed in.
-    InvalidArg(String),
     /// An error when the heim library encounters a problem.
+    #[error("Error caused by Heim, {0}")]
     InvalidHeim(String),
     /// An error when the Crossterm library encounters a problem.
+    #[error("Error caused by Crossterm, {0}")]
     CrosstermError(String),
     /// An error to represent generic errors.
+    #[error("Generic error, {0}")]
     GenericError(String),
     /// An error to represent errors with fern.
+    #[error("Fern error, {0}")]
     FernError(String),
     /// An error to represent errors with the config.
+    #[error("Configuration file error, {0}")]
     ConfigError(String),
     /// An error to represent errors with converting between data types.
+    #[error("Conversion error, {0}")]
     ConversionError(String),
     /// An error to represent errors with querying.
+    #[error("Query error, {0}")]
     QueryError(Cow<'static, str>),
     /// An error that just signifies something minor went wrong; no message.
-    MinorError(),
-}
-
-impl std::fmt::Display for BottomError {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match *self {
-            BottomError::InvalidIO(ref message) => {
-                write!(f, "encountered an IO exception: {}", message)
-            }
-            BottomError::InvalidArg(ref message) => write!(f, "Invalid argument: {}", message),
-            BottomError::InvalidHeim(ref message) => write!(
-                f,
-                "invalid error during data collection due to heim: {}",
-                message
-            ),
-            BottomError::CrosstermError(ref message) => {
-                write!(f, "invalid error due to Crossterm: {}", message)
-            }
-            BottomError::GenericError(ref message) => write!(f, "{}", message),
-            BottomError::FernError(ref message) => write!(f, "Invalid fern error: {}", message),
-            BottomError::ConfigError(ref message) => {
-                write!(f, "invalid config file error: {}", message)
-            }
-            BottomError::ConversionError(ref message) => {
-                write!(f, "unable to convert: {}", message)
-            }
-            BottomError::QueryError(ref message) => write!(f, "{}", message),
-            BottomError::MinorError() => write!(f, "Minor error."),
-        }
-    }
+    #[error("Minor error.")]
+    MinorError,
 }
 
 impl From<std::io::Error> for BottomError {
@@ -77,7 +56,7 @@ impl From<crossterm::ErrorKind> for BottomError {
 
 impl From<std::num::ParseIntError> for BottomError {
     fn from(err: std::num::ParseIntError) -> Self {
-        BottomError::InvalidArg(err.to_string())
+        BottomError::ConfigError(err.to_string())
     }
 }
 
diff --git a/tests/arg_tests.rs b/tests/arg_tests.rs
index 134d9615..f6dac340 100644
--- a/tests/arg_tests.rs
+++ b/tests/arg_tests.rs
@@ -18,7 +18,7 @@ fn test_small_rate() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your update rate to be at least 250 milliseconds.",
+            "set your update rate to be at least 250 milliseconds.",
         ));
     Ok(())
 }
@@ -31,7 +31,7 @@ fn test_large_default_time() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your default value to be at most",
+            "set your default value to be at most",
         ));
     Ok(())
 }
@@ -44,7 +44,7 @@ fn test_small_default_time() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your default value to be at least",
+            "set your default value to be at least",
         ));
     Ok(())
 }
@@ -57,7 +57,7 @@ fn test_large_delta_time() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your time delta to be at most",
+            "set your time delta to be at most",
         ));
     Ok(())
 }
@@ -70,7 +70,7 @@ fn test_small_delta_time() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your time delta to be at least",
+            "set your time delta to be at least",
         ));
     Ok(())
 }
@@ -83,7 +83,7 @@ fn test_large_rate() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your update rate to be at most unsigned INT_MAX.",
+            "set your update rate to be at most unsigned INT_MAX.",
         ));
     Ok(())
 }
@@ -136,7 +136,7 @@ fn test_invalid_default_widget_1() -> Result<(), Box<dyn std::error::Error>> {
         .arg("fake_widget")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid widget type"));
+        .stderr(predicate::str::contains("invalid widget name"));
 
     Ok(())
 }
@@ -151,7 +151,7 @@ fn test_invalid_default_widget_2() -> Result<(), Box<dyn std::error::Error>> {
         .assert()
         .failure()
         .stderr(predicate::str::contains(
-            "Please set your widget count to be at most unsigned INT_MAX",
+            "set your widget count to be at most unsigned INT_MAX",
         ));
 
     Ok(())
diff --git a/tests/invalid_config_tests.rs b/tests/invalid_config_tests.rs
index 34b8e06e..cda6beb5 100644
--- a/tests/invalid_config_tests.rs
+++ b/tests/invalid_config_tests.rs
@@ -26,7 +26,7 @@ fn test_empty_layout() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/empty_layout.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid layout config"));
+        .stderr(predicate::str::contains("at least one widget"));
     Ok(())
 }
 
@@ -37,7 +37,7 @@ fn test_invalid_layout_widget_type() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_layout_widget_type.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid widget type"));
+        .stderr(predicate::str::contains("invalid widget name"));
     Ok(())
 }
 
@@ -62,7 +62,7 @@ fn test_invalid_colour_hex() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_hex.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid color hex"));
+        .stderr(predicate::str::contains("invalid hex colour"));
     Ok(())
 }
 
@@ -74,7 +74,7 @@ fn test_invalid_colour_hex_2() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_hex_2.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid color hex"));
+        .stderr(predicate::str::contains("invalid hex colour"));
     Ok(())
 }
 
@@ -87,7 +87,7 @@ fn test_invalid_colour_hex_3() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_hex_3.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid color hex"));
+        .stderr(predicate::str::contains("invalid hex colour"));
     Ok(())
 }
 
@@ -98,7 +98,7 @@ fn test_invalid_colour_name() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_name.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid named color"));
+        .stderr(predicate::str::contains("invalid named colour"));
     Ok(())
 }
 
@@ -109,7 +109,7 @@ fn test_invalid_colour_rgb() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_rgb.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid RGB color"));
+        .stderr(predicate::str::contains("invalid RGB"));
     Ok(())
 }
 
@@ -120,7 +120,7 @@ fn test_invalid_colour_rgb_2() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_rgb_2.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid RGB color"));
+        .stderr(predicate::str::contains("invalid RGB"));
     Ok(())
 }
 
@@ -131,6 +131,19 @@ fn test_invalid_colour_string() -> Result<(), Box<dyn std::error::Error>> {
         .arg("./tests/invalid_configs/invalid_colour_string.toml")
         .assert()
         .failure()
-        .stderr(predicate::str::contains("invalid named color"));
+        .stderr(predicate::str::contains("invalid named colour"));
+    Ok(())
+}
+
+#[test]
+fn test_empty_battery() -> Result<(), Box<dyn std::error::Error>> {
+    Command::new(get_binary_location())
+        .arg("-C")
+        .arg("./tests/invalid_configs/empty_battery.toml")
+        .assert()
+        .failure()
+        .stderr(predicate::str::contains(
+            "battery colour list must have at least one colour.",
+        ));
     Ok(())
 }
diff --git a/tests/invalid_configs/empty_battery.toml b/tests/invalid_configs/empty_battery.toml
new file mode 100644
index 00000000..651f7b58
--- /dev/null
+++ b/tests/invalid_configs/empty_battery.toml
@@ -0,0 +1,2 @@
+[colors]
+battery_colors=[]
\ No newline at end of file