fix(errors): Introduce thiserror to make error types simpler (#836)

This commit is contained in:
Ken Matsui 2021-11-06 04:45:57 +09:00 committed by GitHub
parent c1cf7287ab
commit f9cb23af65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 92 deletions

1
Cargo.lock generated
View file

@ -2926,6 +2926,7 @@ dependencies = [
"strum",
"tempfile",
"termion",
"thiserror",
"unicode-width",
"url",
"vte",

View file

@ -28,6 +28,7 @@ strip-ansi-escapes = "0.1.0"
structopt = "0.3"
strum = "0.20.0"
termion = "1.5.0"
thiserror = "1.0.30"
url = { version = "2.2.2", features = ["serde"] }
vte = "0.10.1"
zellij-tile = { path = "../zellij-tile/", version = "0.20.0" }

View file

@ -1,9 +1,9 @@
//! Deserializes configuration options.
use std::error;
use std::fmt::{self, Display};
use std::fmt;
use std::fs::File;
use std::io::{self, Read};
use std::path::{Path, PathBuf};
use thiserror::Error;
use serde::Deserialize;
use std::convert::{TryFrom, TryInto};
@ -39,20 +39,26 @@ pub struct Config {
pub plugins: PluginsConfig,
}
#[derive(Debug)]
#[derive(Error, Debug)]
pub enum ConfigError {
// Deserialization error
Serde(serde_yaml::Error),
#[error("Deserialization error: {0}")]
Serde(#[from] serde_yaml::Error),
// Io error
Io(io::Error),
#[error("IoError: {0}")]
Io(#[from] io::Error),
// Io error with path context
#[error("IoError: {0}, File: {1}")]
IoPath(io::Error, PathBuf),
// Internal Deserialization Error
FromUtf8(std::string::FromUtf8Error),
#[error("FromUtf8Error: {0}")]
FromUtf8(#[from] std::string::FromUtf8Error),
// Naming a part in a tab is unsupported
LayoutNameInTab(LayoutNameInTabError),
#[error("There was an error in the layout file, {0}")]
LayoutNameInTab(#[from] LayoutNameInTabError),
// Plugins have a semantic error, usually trying to parse two of the same tag
PluginsError(PluginsConfigError),
#[error("PluginsError: {0}")]
PluginsError(#[from] PluginsConfigError),
}
impl Default for Config {
@ -195,66 +201,6 @@ impl std::error::Error for LayoutNameInTabError {
}
}
impl Display for ConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
ConfigError::Io(ref err) => write!(formatter, "IoError: {}", err),
ConfigError::IoPath(ref err, ref path) => {
write!(formatter, "IoError: {}, File: {}", err, path.display(),)
}
ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err),
ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err),
ConfigError::LayoutNameInTab(ref err) => {
write!(formatter, "There was an error in the layout file, {}", err)
}
ConfigError::PluginsError(ref err) => write!(formatter, "PluginsError: {}", err),
}
}
}
impl std::error::Error for ConfigError {
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
ConfigError::Io(ref err) => Some(err),
ConfigError::IoPath(ref err, _) => Some(err),
ConfigError::Serde(ref err) => Some(err),
ConfigError::FromUtf8(ref err) => Some(err),
ConfigError::LayoutNameInTab(ref err) => Some(err),
ConfigError::PluginsError(ref err) => Some(err),
}
}
}
impl From<io::Error> for ConfigError {
fn from(err: io::Error) -> ConfigError {
ConfigError::Io(err)
}
}
impl From<serde_yaml::Error> for ConfigError {
fn from(err: serde_yaml::Error) -> ConfigError {
ConfigError::Serde(err)
}
}
impl From<std::string::FromUtf8Error> for ConfigError {
fn from(err: std::string::FromUtf8Error) -> ConfigError {
ConfigError::FromUtf8(err)
}
}
impl From<LayoutNameInTabError> for ConfigError {
fn from(err: LayoutNameInTabError) -> ConfigError {
ConfigError::LayoutNameInTab(err)
}
}
impl From<PluginsConfigError> for ConfigError {
fn from(err: PluginsConfigError) -> ConfigError {
ConfigError::PluginsError(err)
}
}
// The unit test location.
#[cfg(test)]
mod config_test {

View file

@ -2,9 +2,9 @@
use std::borrow::Borrow;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fmt::{self, Display};
use std::fs;
use std::path::{Path, PathBuf};
use thiserror::Error;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
@ -189,35 +189,16 @@ impl Default for PluginTypeFromYaml {
}
}
#[derive(Debug, PartialEq)]
#[derive(Error, Debug, PartialEq)]
pub enum PluginsConfigError {
#[error("Duplication in plugin tag names is not allowed: '{}'", String::from(.0.clone()))]
DuplicatePlugins(PluginTag),
#[error("Only 'file:' and 'zellij:' url schemes are supported for plugin lookup. '{0}' does not match either.")]
InvalidUrl(Url),
#[error("Could not find plugin at the path: '{0:?}'")]
InvalidPluginLocation(PathBuf),
}
impl std::error::Error for PluginsConfigError {}
impl Display for PluginsConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
PluginsConfigError::DuplicatePlugins(tag) => write!(
formatter,
"Duplication in plugin tag names is not allowed: '{}'",
String::from(tag.clone())
),
PluginsConfigError::InvalidUrl(url) => write!(
formatter,
"Only 'file:' and 'zellij:' url schemes are supported for plugin lookup. '{}' does not match either.",
url
),
PluginsConfigError::InvalidPluginLocation(path) => write!(
formatter,
"Could not find plugin at the path: '{:?}'", path
),
}
}
}
#[cfg(test)]
mod tests {
use super::*;