Drop SnapshotError in favor of anyhow::Error

This commit is contained in:
Lucien Greathouse
2020-12-18 12:16:05 -08:00
parent f3745c68d2
commit 3b149cc875
15 changed files with 70 additions and 183 deletions

View File

@@ -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;
}
};

View File

@@ -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,
},
}

View File

@@ -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)

View File

@@ -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");

View File

@@ -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<PathBuf>) -> Self {
Self::FileNameBadUnicode { path: path.into() }
}
pub(crate) fn file_contents_bad_unicode(
source: std::str::Utf8Error,
path: impl Into<PathBuf>,
) -> Self {
Self::FileContentsBadUnicode {
source,
path: path.into(),
}
}
pub(crate) fn malformed_project(source: ProjectError, path: impl Into<PathBuf>) -> Self {
Self::MalformedProject {
source,
path: path.into(),
}
}
pub(crate) fn malformed_rbxm(
source: rbx_binary::DecodeError,
path: impl Into<PathBuf>,
) -> Self {
Self::MalformedRbxm {
source,
path: path.into(),
}
}
pub(crate) fn malformed_rbxmx(source: rbx_xml::DecodeError, path: impl Into<PathBuf>) -> Self {
Self::MalformedRbxmx {
source,
path: path.into(),
}
}
pub(crate) fn malformed_model_json(
source: serde_json::Error,
path: impl Into<PathBuf>,
) -> Self {
Self::MalformedModelJson {
source,
path: path.into(),
}
}
pub(crate) fn malformed_meta_json(source: serde_json::Error, path: impl Into<PathBuf>) -> Self {
Self::MalformedMetaJson {
source,
path: path.into(),
}
}
pub(crate) fn malformed_json(source: serde_json::Error, path: impl Into<PathBuf>) -> Self {
Self::MalformedJson {
source,
path: path.into(),
}
}
pub(crate) fn malformed_l10n_csv(source: csv::Error, path: impl Into<PathBuf>) -> Self {
Self::MalformedLocalizationCsv {
source,
path: path.into(),
}
}
}

View File

@@ -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();

View File

@@ -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());

View File

@@ -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
);
}

View File

@@ -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<Self, SnapshotError> {
serde_json::from_slice(slice)
.map_err(|source| SnapshotError::malformed_meta_json(source, path))
pub fn from_slice(slice: &[u8], path: &Path) -> anyhow::Result<Self> {
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<Self, SnapshotError> {
serde_json::from_slice(slice)
.map_err(|source| SnapshotError::malformed_meta_json(source, path))
pub fn from_slice(slice: &[u8], path: &Path) -> anyhow::Result<Self> {
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) {

View File

@@ -1,5 +1,3 @@
use crate::snapshot::InstanceSnapshot;
use super::error::SnapshotError;
pub type SnapshotInstanceResult = Result<Option<InstanceSnapshot>, SnapshotError>;
pub type SnapshotInstanceResult = anyhow::Result<Option<InstanceSnapshot>>;

View File

@@ -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(

View File

@@ -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();

View File

@@ -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()
);
}
}

View File

@@ -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()
);
}
}

View File

@@ -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 {