From 3b149cc875df3b3caca3267d2f8b519e800cbbc1 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Fri, 18 Dec 2020 12:16:05 -0800 Subject: [PATCH] Drop SnapshotError in favor of anyhow::Error --- src/change_processor.rs | 4 +- src/serve_session.rs | 6 +- src/snapshot_middleware/csv.rs | 13 ++- src/snapshot_middleware/dir.rs | 7 +- src/snapshot_middleware/error.rs | 130 -------------------------- src/snapshot_middleware/json.rs | 7 +- src/snapshot_middleware/json_model.rs | 5 +- src/snapshot_middleware/lua.rs | 16 ++-- src/snapshot_middleware/meta_file.rs | 23 +++-- src/snapshot_middleware/middleware.rs | 4 +- src/snapshot_middleware/mod.rs | 2 - src/snapshot_middleware/project.rs | 5 +- src/snapshot_middleware/rbxm.rs | 11 ++- src/snapshot_middleware/rbxmx.rs | 11 ++- src/snapshot_middleware/txt.rs | 9 +- 15 files changed, 70 insertions(+), 183 deletions(-) delete mode 100644 src/snapshot_middleware/error.rs diff --git a/src/change_processor.rs b/src/change_processor.rs index 9e7797ee..a6ebdb03 100644 --- a/src/change_processor.rs +++ b/src/change_processor.rs @@ -292,7 +292,7 @@ fn compute_and_apply_changes(tree: &mut RojoTree, vfs: &Vfs, id: RbxId) -> Optio return None; } Err(err) => { - log::error!("Snapshot error: {}", ErrorDisplay(err)); + log::error!("Snapshot error: {:?}", err); return None; } }; @@ -340,7 +340,7 @@ fn compute_and_apply_changes(tree: &mut RojoTree, vfs: &Vfs, id: RbxId) -> Optio return None; } Err(err) => { - log::error!("{}", ErrorDisplay(err)); + log::error!("{:?}", err); return None; } }; diff --git a/src/serve_session.rs b/src/serve_session.rs index d43d4981..ee6020a6 100644 --- a/src/serve_session.rs +++ b/src/serve_session.rs @@ -22,7 +22,7 @@ use crate::{ apply_patch_set, compute_patch_set, AppliedPatchSet, InstanceContext, InstancePropertiesWithMeta, PatchSet, RojoTree, }, - snapshot_middleware::{snapshot_from_vfs, SnapshotError}, + snapshot_middleware::snapshot_from_vfs, }; /// Contains all of the state for a Rojo serve session. @@ -234,8 +234,8 @@ pub enum ServeSessionError { }, #[error(transparent)] - Snapshot { + Other { #[from] - source: SnapshotError, + source: anyhow::Error, }, } diff --git a/src/snapshot_middleware/csv.rs b/src/snapshot_middleware/csv.rs index fcd358f6..fd39b04e 100644 --- a/src/snapshot_middleware/csv.rs +++ b/src/snapshot_middleware/csv.rs @@ -1,5 +1,6 @@ use std::{collections::BTreeMap, path::Path}; +use anyhow::Context; use maplit::hashmap; use memofs::{IoResultExt, Vfs}; use rbx_dom_weak::RbxValue; @@ -7,9 +8,7 @@ use serde::Serialize; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; -use super::{ - error::SnapshotError, meta_file::AdjacentMetadata, middleware::SnapshotInstanceResult, -}; +use super::{meta_file::AdjacentMetadata, middleware::SnapshotInstanceResult}; pub fn snapshot_csv( _context: &InstanceContext, @@ -20,8 +19,12 @@ pub fn snapshot_csv( let meta_path = path.with_file_name(format!("{}.meta.json", instance_name)); let contents = vfs.read(path)?; - let table_contents = convert_localization_csv(&contents) - .map_err(|source| SnapshotError::malformed_l10n_csv(source, path))?; + let table_contents = convert_localization_csv(&contents).with_context(|| { + format!( + "File was not a valid LocalizationTable CSV file: {}", + path.display() + ) + })?; let mut snapshot = InstanceSnapshot::new() .name(instance_name) diff --git a/src/snapshot_middleware/dir.rs b/src/snapshot_middleware/dir.rs index 359856d0..84c7d64a 100644 --- a/src/snapshot_middleware/dir.rs +++ b/src/snapshot_middleware/dir.rs @@ -4,10 +4,7 @@ use memofs::{DirEntry, IoResultExt, Vfs}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; -use super::{ - error::SnapshotError, meta_file::DirectoryMetadata, middleware::SnapshotInstanceResult, - snapshot_from_vfs, -}; +use super::{meta_file::DirectoryMetadata, middleware::SnapshotInstanceResult, snapshot_from_vfs}; pub fn snapshot_dir(context: &InstanceContext, vfs: &Vfs, path: &Path) -> SnapshotInstanceResult { let passes_filter_rules = |child: &DirEntry| { @@ -35,7 +32,7 @@ pub fn snapshot_dir(context: &InstanceContext, vfs: &Vfs, path: &Path) -> Snapsh .file_name() .expect("Could not extract file name") .to_str() - .ok_or_else(|| SnapshotError::file_name_bad_unicode(path))? + .ok_or_else(|| anyhow::anyhow!("File name was not valid UTF-8: {}", path.display()))? .to_string(); let meta_path = path.join("init.meta.json"); diff --git a/src/snapshot_middleware/error.rs b/src/snapshot_middleware/error.rs deleted file mode 100644 index 145c44ec..00000000 --- a/src/snapshot_middleware/error.rs +++ /dev/null @@ -1,130 +0,0 @@ -use std::{io, path::PathBuf}; - -use thiserror::Error; - -use crate::project::ProjectError; - -#[derive(Debug, Error)] -pub enum SnapshotError { - #[error("file name had malformed Unicode")] - FileNameBadUnicode { path: PathBuf }, - - #[error("file had malformed Unicode contents at path {}", .path.display())] - FileContentsBadUnicode { - source: std::str::Utf8Error, - path: PathBuf, - }, - - #[error("malformed project file at path {}", .path.display())] - MalformedProject { source: ProjectError, path: PathBuf }, - - #[error("malformed .rbxm file at path {}", .path.display())] - MalformedRbxm { - source: rbx_binary::DecodeError, - path: PathBuf, - }, - - #[error("malformed .rbxmx file at path {}", .path.display())] - MalformedRbxmx { - source: rbx_xml::DecodeError, - path: PathBuf, - }, - - #[error("malformed .model.json file at path {}", .path.display())] - MalformedModelJson { - source: serde_json::Error, - path: PathBuf, - }, - - #[error("malformed .meta.json file at path {}", .path.display())] - MalformedMetaJson { - source: serde_json::Error, - path: PathBuf, - }, - - #[error("malformed JSON at path {}", .path.display())] - MalformedJson { - source: serde_json::Error, - path: PathBuf, - }, - - #[error("malformed CSV localization data at path {}", .path.display())] - MalformedLocalizationCsv { source: csv::Error, path: PathBuf }, - - #[error(transparent)] - Io { - #[from] - source: io::Error, - }, -} - -impl SnapshotError { - pub(crate) fn file_name_bad_unicode(path: impl Into) -> Self { - Self::FileNameBadUnicode { path: path.into() } - } - - pub(crate) fn file_contents_bad_unicode( - source: std::str::Utf8Error, - path: impl Into, - ) -> Self { - Self::FileContentsBadUnicode { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_project(source: ProjectError, path: impl Into) -> Self { - Self::MalformedProject { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_rbxm( - source: rbx_binary::DecodeError, - path: impl Into, - ) -> Self { - Self::MalformedRbxm { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_rbxmx(source: rbx_xml::DecodeError, path: impl Into) -> Self { - Self::MalformedRbxmx { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_model_json( - source: serde_json::Error, - path: impl Into, - ) -> Self { - Self::MalformedModelJson { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_meta_json(source: serde_json::Error, path: impl Into) -> Self { - Self::MalformedMetaJson { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_json(source: serde_json::Error, path: impl Into) -> Self { - Self::MalformedJson { - source, - path: path.into(), - } - } - - pub(crate) fn malformed_l10n_csv(source: csv::Error, path: impl Into) -> Self { - Self::MalformedLocalizationCsv { - source, - path: path.into(), - } - } -} diff --git a/src/snapshot_middleware/json.rs b/src/snapshot_middleware/json.rs index 15efe21b..959b3cb3 100644 --- a/src/snapshot_middleware/json.rs +++ b/src/snapshot_middleware/json.rs @@ -1,5 +1,6 @@ use std::path::Path; +use anyhow::Context; use maplit::hashmap; use memofs::{IoResultExt, Vfs}; use rbx_dom_weak::RbxValue; @@ -9,9 +10,7 @@ use crate::{ snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}, }; -use super::{ - error::SnapshotError, meta_file::AdjacentMetadata, middleware::SnapshotInstanceResult, -}; +use super::{meta_file::AdjacentMetadata, middleware::SnapshotInstanceResult}; pub fn snapshot_json( context: &InstanceContext, @@ -22,7 +21,7 @@ pub fn snapshot_json( let contents = vfs.read(path)?; let value: serde_json::Value = serde_json::from_slice(&contents) - .map_err(|err| SnapshotError::malformed_json(err, path))?; + .with_context(|| format!("File contains malformed JSON: {}", path.display()))?; let as_lua = json_to_lua(value).to_string(); diff --git a/src/snapshot_middleware/json_model.rs b/src/snapshot_middleware/json_model.rs index c978f57a..b0dd361c 100644 --- a/src/snapshot_middleware/json_model.rs +++ b/src/snapshot_middleware/json_model.rs @@ -1,5 +1,6 @@ use std::{borrow::Cow, collections::HashMap, path::Path}; +use anyhow::Context; use memofs::Vfs; use rbx_dom_weak::UnresolvedRbxValue; use rbx_reflection::try_resolve_value; @@ -7,7 +8,7 @@ use serde::Deserialize; use crate::snapshot::{InstanceContext, InstanceSnapshot}; -use super::{error::SnapshotError, middleware::SnapshotInstanceResult}; +use super::middleware::SnapshotInstanceResult; pub fn snapshot_json_model( context: &InstanceContext, @@ -17,7 +18,7 @@ pub fn snapshot_json_model( ) -> SnapshotInstanceResult { let contents = vfs.read(path)?; let instance: JsonModel = serde_json::from_slice(&contents) - .map_err(|source| SnapshotError::malformed_model_json(source, path))?; + .with_context(|| format!("File is not a valid JSON model: {}", path.display()))?; let mut snapshot = instance.core.into_snapshot(instance_name.to_owned()); diff --git a/src/snapshot_middleware/lua.rs b/src/snapshot_middleware/lua.rs index 668f57a7..bfea5324 100644 --- a/src/snapshot_middleware/lua.rs +++ b/src/snapshot_middleware/lua.rs @@ -1,5 +1,6 @@ use std::{path::Path, str}; +use anyhow::Context; use maplit::hashmap; use memofs::{IoResultExt, Vfs}; use rbx_dom_weak::RbxValue; @@ -28,9 +29,8 @@ pub fn snapshot_lua(context: &InstanceContext, vfs: &Vfs, path: &Path) -> Snapsh let contents = vfs.read(path)?; let contents_str = str::from_utf8(&contents) - // TODO: Turn into error type - .expect("File content was not valid UTF-8") - .to_string(); + .with_context(|| format!("File was not valid UTF-8: {}", path.display()))? + .to_owned(); let meta_path = path.with_file_name(format!("{}.meta.json", instance_name)); @@ -71,10 +71,14 @@ pub fn snapshot_lua_init( let dir_snapshot = snapshot_dir(context, vfs, folder_path)?.unwrap(); if dir_snapshot.class_name != "Folder" { - panic!( + anyhow::bail!( "init.lua, init.server.lua, and init.client.lua can \ - only be used if the instance produced by the parent \ - directory would be a Folder." + only be used if the instance produced by the containing \ + directory would be a Folder.\n\n\ + + The directory {} turned into an instance of class {}.", + folder_path.display(), + dir_snapshot.class_name ); } diff --git a/src/snapshot_middleware/meta_file.rs b/src/snapshot_middleware/meta_file.rs index 57f1e318..618f72c6 100644 --- a/src/snapshot_middleware/meta_file.rs +++ b/src/snapshot_middleware/meta_file.rs @@ -1,13 +1,12 @@ use std::{borrow::Cow, collections::HashMap, path::Path}; +use anyhow::Context; use rbx_dom_weak::UnresolvedRbxValue; use rbx_reflection::try_resolve_value; use serde::{Deserialize, Serialize}; use crate::snapshot::InstanceSnapshot; -use super::error::SnapshotError; - /// Represents metadata in a sibling file with the same basename. /// /// As an example, hello.meta.json next to hello.lua would allow assigning @@ -23,9 +22,13 @@ pub struct AdjacentMetadata { } impl AdjacentMetadata { - pub fn from_slice(slice: &[u8], path: &Path) -> Result { - serde_json::from_slice(slice) - .map_err(|source| SnapshotError::malformed_meta_json(source, path)) + pub fn from_slice(slice: &[u8], path: &Path) -> anyhow::Result { + serde_json::from_slice(slice).with_context(|| { + format!( + "File contained malformed .meta.json data: {}", + path.display() + ) + }) } pub fn apply_ignore_unknown_instances(&mut self, snapshot: &mut InstanceSnapshot) { @@ -75,9 +78,13 @@ pub struct DirectoryMetadata { } impl DirectoryMetadata { - pub fn from_slice(slice: &[u8], path: &Path) -> Result { - serde_json::from_slice(slice) - .map_err(|source| SnapshotError::malformed_meta_json(source, path)) + pub fn from_slice(slice: &[u8], path: &Path) -> anyhow::Result { + serde_json::from_slice(slice).with_context(|| { + format!( + "File contained malformed init.meta.json data: {}", + path.display() + ) + }) } pub fn apply_all(&mut self, snapshot: &mut InstanceSnapshot) { diff --git a/src/snapshot_middleware/middleware.rs b/src/snapshot_middleware/middleware.rs index b05f0b9e..f576ede8 100644 --- a/src/snapshot_middleware/middleware.rs +++ b/src/snapshot_middleware/middleware.rs @@ -1,5 +1,3 @@ use crate::snapshot::InstanceSnapshot; -use super::error::SnapshotError; - -pub type SnapshotInstanceResult = Result, SnapshotError>; +pub type SnapshotInstanceResult = anyhow::Result>; diff --git a/src/snapshot_middleware/mod.rs b/src/snapshot_middleware/mod.rs index 9563d8b6..bf9f4e8c 100644 --- a/src/snapshot_middleware/mod.rs +++ b/src/snapshot_middleware/mod.rs @@ -5,7 +5,6 @@ mod csv; mod dir; -mod error; mod json; mod json_model; mod lua; @@ -37,7 +36,6 @@ use self::{ util::match_file_name, }; -pub use self::error::*; pub use self::project::snapshot_project_node; pub fn snapshot_from_vfs( diff --git a/src/snapshot_middleware/project.rs b/src/snapshot_middleware/project.rs index 94414bd5..c644c396 100644 --- a/src/snapshot_middleware/project.rs +++ b/src/snapshot_middleware/project.rs @@ -1,5 +1,6 @@ use std::{borrow::Cow, collections::HashMap, path::Path}; +use anyhow::Context; use memofs::Vfs; use rbx_reflection::{get_class_descriptor, try_resolve_value}; @@ -10,7 +11,7 @@ use crate::{ }, }; -use super::{error::SnapshotError, middleware::SnapshotInstanceResult, snapshot_from_vfs}; +use super::{middleware::SnapshotInstanceResult, snapshot_from_vfs}; pub fn snapshot_project( context: &InstanceContext, @@ -18,7 +19,7 @@ pub fn snapshot_project( path: &Path, ) -> SnapshotInstanceResult { let project = Project::load_from_slice(&vfs.read(path)?, path) - .map_err(|err| SnapshotError::malformed_project(err, path))?; + .with_context(|| format!("File was not a valid Rojo project: {}", path.display()))?; let mut context = context.clone(); diff --git a/src/snapshot_middleware/rbxm.rs b/src/snapshot_middleware/rbxm.rs index 9d2dc4b6..68080b1d 100644 --- a/src/snapshot_middleware/rbxm.rs +++ b/src/snapshot_middleware/rbxm.rs @@ -1,11 +1,12 @@ use std::{collections::HashMap, path::Path}; +use anyhow::Context; use memofs::Vfs; use rbx_dom_weak::{RbxInstanceProperties, RbxTree}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; -use super::{middleware::SnapshotInstanceResult, SnapshotError}; +use super::middleware::SnapshotInstanceResult; pub fn snapshot_rbxm( context: &InstanceContext, @@ -21,7 +22,7 @@ pub fn snapshot_rbxm( let root_id = temp_tree.get_root_id(); rbx_binary::decode(&mut temp_tree, root_id, vfs.read(path)?.as_slice()) - .map_err(|err| SnapshotError::malformed_rbxm(err, path))?; + .with_context(|| format!("Malformed rbxm file: {}", path.display()))?; let root_instance = temp_tree.get_instance(root_id).unwrap(); let children = root_instance.get_children_ids(); @@ -38,7 +39,11 @@ pub fn snapshot_rbxm( Ok(Some(snapshot)) } else { - panic!("Rojo doesn't have support for model files with zero or more than one top-level instances yet."); + anyhow::bail!( + "Rojo doesn't have support for model files with zero or more than one top-level instances yet.\n\n \ + Check the model file at path {}", + path.display() + ); } } diff --git a/src/snapshot_middleware/rbxmx.rs b/src/snapshot_middleware/rbxmx.rs index 753bdc7d..e24a6f58 100644 --- a/src/snapshot_middleware/rbxmx.rs +++ b/src/snapshot_middleware/rbxmx.rs @@ -1,10 +1,11 @@ use std::path::Path; +use anyhow::Context; use memofs::Vfs; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; -use super::{middleware::SnapshotInstanceResult, SnapshotError}; +use super::middleware::SnapshotInstanceResult; pub fn snapshot_rbxmx( context: &InstanceContext, @@ -16,7 +17,7 @@ pub fn snapshot_rbxmx( .property_behavior(rbx_xml::DecodePropertyBehavior::ReadUnknown); let temp_tree = rbx_xml::from_reader(vfs.read(path)?.as_slice(), options) - .map_err(|err| SnapshotError::malformed_rbxmx(err, path))?; + .with_context(|| format!("Malformed rbxm file: {}", path.display()))?; let root_instance = temp_tree.get_instance(temp_tree.get_root_id()).unwrap(); let children = root_instance.get_children_ids(); @@ -33,7 +34,11 @@ pub fn snapshot_rbxmx( Ok(Some(snapshot)) } else { - panic!("Rojo doesn't have support for model files with zero or more than one top-level instances yet."); + anyhow::bail!( + "Rojo doesn't have support for model files with zero or more than one top-level instances yet.\n\n \ + Check the model file at path {}", + path.display() + ); } } diff --git a/src/snapshot_middleware/txt.rs b/src/snapshot_middleware/txt.rs index edf1fbf5..4e408475 100644 --- a/src/snapshot_middleware/txt.rs +++ b/src/snapshot_middleware/txt.rs @@ -1,14 +1,13 @@ use std::{path::Path, str}; +use anyhow::Context; use maplit::hashmap; use memofs::{IoResultExt, Vfs}; use rbx_dom_weak::RbxValue; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; -use super::{ - error::SnapshotError, meta_file::AdjacentMetadata, middleware::SnapshotInstanceResult, -}; +use super::{meta_file::AdjacentMetadata, middleware::SnapshotInstanceResult}; pub fn snapshot_txt( context: &InstanceContext, @@ -18,8 +17,8 @@ pub fn snapshot_txt( ) -> SnapshotInstanceResult { let contents = vfs.read(path)?; let contents_str = str::from_utf8(&contents) - .map_err(|err| SnapshotError::file_contents_bad_unicode(err, path))? - .to_string(); + .with_context(|| format!("File was not valid UTF-8: {}", path.display()))? + .to_owned(); let properties = hashmap! { "Value".to_owned() => RbxValue::String {