mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-25 15:16:07 +00:00
Improve error messages from bad snapshots
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
* Fixed plugin assets flashing in on first load ([#121](https://github.com/LPGhatguy/rojo/issues/121))
|
* Fixed plugin assets flashing in on first load ([#121](https://github.com/LPGhatguy/rojo/issues/121))
|
||||||
* Changed Rojo's HTTP server from Rouille to Hyper, which reduced the release size by around a megabyte.
|
* Changed Rojo's HTTP server from Rouille to Hyper, which reduced the release size by around a megabyte.
|
||||||
* Added property type inference to projects, which makes specifying services a lot easier ([#130](https://github.com/LPGhatguy/rojo/pull/130))
|
* Added property type inference to projects, which makes specifying services a lot easier ([#130](https://github.com/LPGhatguy/rojo/pull/130))
|
||||||
|
* Made error messages from invalid and missing files more user-friendly
|
||||||
|
|
||||||
## [0.5.0 Alpha 4](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.4) (February 8, 2019)
|
## [0.5.0 Alpha 4](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.4) (February 8, 2019)
|
||||||
* Added support for nested partitions ([#102](https://github.com/LPGhatguy/rojo/issues/102))
|
* Added support for nested partitions ([#102](https://github.com/LPGhatguy/rojo/issues/102))
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ use log::info;
|
|||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
rbx_session::construct_oneoff_tree,
|
|
||||||
project::{Project, ProjectLoadFuzzyError},
|
|
||||||
imfs::{Imfs, FsError},
|
imfs::{Imfs, FsError},
|
||||||
|
project::{Project, ProjectLoadFuzzyError},
|
||||||
|
rbx_session::construct_oneoff_tree,
|
||||||
|
rbx_snapshot::SnapshotError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@@ -59,6 +60,9 @@ pub enum BuildError {
|
|||||||
|
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
FsError(#[fail(cause)] FsError),
|
FsError(#[fail(cause)] FsError),
|
||||||
|
|
||||||
|
#[fail(display = "{}", _0)]
|
||||||
|
SnapshotError(#[fail(cause)] SnapshotError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_from!(BuildError {
|
impl_from!(BuildError {
|
||||||
@@ -67,6 +71,7 @@ impl_from!(BuildError {
|
|||||||
rbx_xml::EncodeError => XmlModelEncodeError,
|
rbx_xml::EncodeError => XmlModelEncodeError,
|
||||||
rbx_binary::EncodeError => BinaryModelEncodeError,
|
rbx_binary::EncodeError => BinaryModelEncodeError,
|
||||||
FsError => FsError,
|
FsError => FsError,
|
||||||
|
SnapshotError => SnapshotError,
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
||||||
@@ -86,7 +91,7 @@ pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
|||||||
|
|
||||||
let mut imfs = Imfs::new();
|
let mut imfs = Imfs::new();
|
||||||
imfs.add_roots_from_project(&project)?;
|
imfs.add_roots_from_project(&project)?;
|
||||||
let tree = construct_oneoff_tree(&project, &imfs);
|
let tree = construct_oneoff_tree(&project, &imfs)?;
|
||||||
let mut file = File::create(&options.output_file)?;
|
let mut file = File::create(&options.output_file)?;
|
||||||
|
|
||||||
match output_kind {
|
match output_kind {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
project::{Project, ProjectLoadFuzzyError},
|
project::{Project, ProjectLoadFuzzyError},
|
||||||
web::LiveServer,
|
web::LiveServer,
|
||||||
imfs::FsError,
|
imfs::FsError,
|
||||||
live_session::LiveSession,
|
live_session::{LiveSession, LiveSessionError},
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_PORT: u16 = 34872;
|
const DEFAULT_PORT: u16 = 34872;
|
||||||
@@ -28,11 +28,15 @@ pub enum ServeError {
|
|||||||
|
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
FsError(#[fail(cause)] FsError),
|
FsError(#[fail(cause)] FsError),
|
||||||
|
|
||||||
|
#[fail(display = "{}", _0)]
|
||||||
|
LiveSessionError(#[fail(cause)] LiveSessionError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_from!(ServeError {
|
impl_from!(ServeError {
|
||||||
ProjectLoadFuzzyError => ProjectLoadError,
|
ProjectLoadFuzzyError => ProjectLoadError,
|
||||||
FsError => FsError,
|
FsError => FsError,
|
||||||
|
LiveSessionError => LiveSessionError,
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn serve(options: &ServeOptions) -> Result<(), ServeError> {
|
pub fn serve(options: &ServeOptions) -> Result<(), ServeError> {
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ use failure::Fail;
|
|||||||
use reqwest::header::{ACCEPT, USER_AGENT, CONTENT_TYPE, COOKIE};
|
use reqwest::header::{ACCEPT, USER_AGENT, CONTENT_TYPE, COOKIE};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
rbx_session::construct_oneoff_tree,
|
|
||||||
project::{Project, ProjectLoadFuzzyError},
|
|
||||||
imfs::{Imfs, FsError},
|
imfs::{Imfs, FsError},
|
||||||
|
project::{Project, ProjectLoadFuzzyError},
|
||||||
|
rbx_session::construct_oneoff_tree,
|
||||||
|
rbx_snapshot::SnapshotError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
@@ -36,6 +37,9 @@ pub enum UploadError {
|
|||||||
|
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
FsError(#[fail(cause)] FsError),
|
FsError(#[fail(cause)] FsError),
|
||||||
|
|
||||||
|
#[fail(display = "{}", _0)]
|
||||||
|
SnapshotError(#[fail(cause)] SnapshotError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_from!(UploadError {
|
impl_from!(UploadError {
|
||||||
@@ -44,6 +48,7 @@ impl_from!(UploadError {
|
|||||||
reqwest::Error => HttpError,
|
reqwest::Error => HttpError,
|
||||||
rbx_xml::EncodeError => XmlModelEncodeError,
|
rbx_xml::EncodeError => XmlModelEncodeError,
|
||||||
FsError => FsError,
|
FsError => FsError,
|
||||||
|
SnapshotError => SnapshotError,
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -67,7 +72,7 @@ pub fn upload(options: &UploadOptions) -> Result<(), UploadError> {
|
|||||||
|
|
||||||
let mut imfs = Imfs::new();
|
let mut imfs = Imfs::new();
|
||||||
imfs.add_roots_from_project(&project)?;
|
imfs.add_roots_from_project(&project)?;
|
||||||
let tree = construct_oneoff_tree(&project, &imfs);
|
let tree = construct_oneoff_tree(&project, &imfs)?;
|
||||||
|
|
||||||
let root_id = tree.get_root_id();
|
let root_id = tree.get_root_id();
|
||||||
let mut contents = Vec::new();
|
let mut contents = Vec::new();
|
||||||
|
|||||||
@@ -2,16 +2,33 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use failure::Fail;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fs_watcher::FsWatcher,
|
fs_watcher::FsWatcher,
|
||||||
imfs::{Imfs, FsError},
|
imfs::{Imfs, FsError},
|
||||||
message_queue::MessageQueue,
|
message_queue::MessageQueue,
|
||||||
project::Project,
|
project::Project,
|
||||||
rbx_session::RbxSession,
|
rbx_session::RbxSession,
|
||||||
|
rbx_snapshot::SnapshotError,
|
||||||
session_id::SessionId,
|
session_id::SessionId,
|
||||||
snapshot_reconciler::InstanceChanges,
|
snapshot_reconciler::InstanceChanges,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Fail)]
|
||||||
|
pub enum LiveSessionError {
|
||||||
|
#[fail(display = "{}", _0)]
|
||||||
|
Fs(#[fail(cause)] FsError),
|
||||||
|
|
||||||
|
#[fail(display = "{}", _0)]
|
||||||
|
Snapshot(#[fail(cause)] SnapshotError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_from!(LiveSessionError {
|
||||||
|
FsError => Fs,
|
||||||
|
SnapshotError => Snapshot,
|
||||||
|
});
|
||||||
|
|
||||||
/// Contains all of the state for a Rojo live-sync session.
|
/// Contains all of the state for a Rojo live-sync session.
|
||||||
pub struct LiveSession {
|
pub struct LiveSession {
|
||||||
pub project: Arc<Project>,
|
pub project: Arc<Project>,
|
||||||
@@ -23,7 +40,7 @@ pub struct LiveSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LiveSession {
|
impl LiveSession {
|
||||||
pub fn new(project: Arc<Project>) -> Result<LiveSession, FsError> {
|
pub fn new(project: Arc<Project>) -> Result<LiveSession, LiveSessionError> {
|
||||||
let imfs = {
|
let imfs = {
|
||||||
let mut imfs = Imfs::new();
|
let mut imfs = Imfs::new();
|
||||||
imfs.add_roots_from_project(&project)?;
|
imfs.add_roots_from_project(&project)?;
|
||||||
@@ -36,7 +53,7 @@ impl LiveSession {
|
|||||||
Arc::clone(&project),
|
Arc::clone(&project),
|
||||||
Arc::clone(&imfs),
|
Arc::clone(&imfs),
|
||||||
Arc::clone(&message_queue),
|
Arc::clone(&message_queue),
|
||||||
)));
|
)?));
|
||||||
|
|
||||||
let fs_watcher = FsWatcher::start(
|
let fs_watcher = FsWatcher::start(
|
||||||
Arc::clone(&imfs),
|
Arc::clone(&imfs),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::{
|
|||||||
|
|
||||||
use rlua::Lua;
|
use rlua::Lua;
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde_derive::{Serialize, Deserialize};
|
||||||
use log::{info, trace};
|
use log::{info, trace, error};
|
||||||
use rbx_dom_weak::{RbxTree, RbxId};
|
use rbx_dom_weak::{RbxTree, RbxId};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -17,6 +17,7 @@ use crate::{
|
|||||||
imfs::{Imfs, ImfsItem},
|
imfs::{Imfs, ImfsItem},
|
||||||
path_map::PathMap,
|
path_map::PathMap,
|
||||||
rbx_snapshot::{
|
rbx_snapshot::{
|
||||||
|
SnapshotError,
|
||||||
SnapshotContext,
|
SnapshotContext,
|
||||||
SnapshotPluginContext,
|
SnapshotPluginContext,
|
||||||
SnapshotPluginEntry,
|
SnapshotPluginEntry,
|
||||||
@@ -31,6 +32,12 @@ const INIT_SCRIPT: &str = "init.lua";
|
|||||||
const INIT_SERVER_SCRIPT: &str = "init.server.lua";
|
const INIT_SERVER_SCRIPT: &str = "init.server.lua";
|
||||||
const INIT_CLIENT_SCRIPT: &str = "init.client.lua";
|
const INIT_CLIENT_SCRIPT: &str = "init.client.lua";
|
||||||
|
|
||||||
|
fn show_snapshot_error(path: &Path, error: SnapshotError) {
|
||||||
|
error!("Rojo couldn't turn one of the project's files into Roblox instances.");
|
||||||
|
error!("Any changes to the file have been ignored.");
|
||||||
|
error!("{}", error);
|
||||||
|
}
|
||||||
|
|
||||||
/// `source_path` or `project_definition` or both must both be Some.
|
/// `source_path` or `project_definition` or both must both be Some.
|
||||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
|
||||||
pub struct MetadataPerInstance {
|
pub struct MetadataPerInstance {
|
||||||
@@ -66,7 +73,7 @@ impl RbxSession {
|
|||||||
project: Arc<Project>,
|
project: Arc<Project>,
|
||||||
imfs: Arc<Mutex<Imfs>>,
|
imfs: Arc<Mutex<Imfs>>,
|
||||||
message_queue: Arc<MessageQueue<InstanceChanges>>,
|
message_queue: Arc<MessageQueue<InstanceChanges>>,
|
||||||
) -> RbxSession {
|
) -> Result<RbxSession, SnapshotError> {
|
||||||
let mut instances_per_path = PathMap::new();
|
let mut instances_per_path = PathMap::new();
|
||||||
let mut metadata_per_instance = HashMap::new();
|
let mut metadata_per_instance = HashMap::new();
|
||||||
|
|
||||||
@@ -104,16 +111,22 @@ impl RbxSession {
|
|||||||
|
|
||||||
let tree = {
|
let tree = {
|
||||||
let temp_imfs = imfs.lock().unwrap();
|
let temp_imfs = imfs.lock().unwrap();
|
||||||
reify_initial_tree(&project, &context, &temp_imfs, &mut instances_per_path, &mut metadata_per_instance)
|
reify_initial_tree(
|
||||||
|
&project,
|
||||||
|
&context,
|
||||||
|
&temp_imfs,
|
||||||
|
&mut instances_per_path,
|
||||||
|
&mut metadata_per_instance,
|
||||||
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
RbxSession {
|
Ok(RbxSession {
|
||||||
tree,
|
tree,
|
||||||
instances_per_path,
|
instances_per_path,
|
||||||
metadata_per_instance,
|
metadata_per_instance,
|
||||||
message_queue,
|
message_queue,
|
||||||
imfs,
|
imfs,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path_created_or_updated(&mut self, path: &Path) {
|
fn path_created_or_updated(&mut self, path: &Path) {
|
||||||
@@ -155,20 +168,24 @@ impl RbxSession {
|
|||||||
let maybe_snapshot = match &instance_metadata.project_definition {
|
let maybe_snapshot = match &instance_metadata.project_definition {
|
||||||
Some((instance_name, project_node)) => {
|
Some((instance_name, project_node)) => {
|
||||||
snapshot_project_node(&context, &imfs, &project_node, Cow::Owned(instance_name.clone()))
|
snapshot_project_node(&context, &imfs, &project_node, Cow::Owned(instance_name.clone()))
|
||||||
.unwrap_or_else(|_| panic!("Could not generate instance snapshot for path {}", path_to_snapshot.display()))
|
// .unwrap_or_else(|_| panic!("Could not generate instance snapshot for path {}", path_to_snapshot.display()))
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
snapshot_imfs_path(&context, &imfs, &path_to_snapshot, None)
|
snapshot_imfs_path(&context, &imfs, &path_to_snapshot, None)
|
||||||
.unwrap_or_else(|_| panic!("Could not generate instance snapshot for path {}", path_to_snapshot.display()))
|
// .unwrap_or_else(|_| panic!("Could not generate instance snapshot for path {}", path_to_snapshot.display()))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshot = match maybe_snapshot {
|
let snapshot = match maybe_snapshot {
|
||||||
Some(snapshot) => snapshot,
|
Ok(Some(snapshot)) => snapshot,
|
||||||
None => {
|
Ok(None) => {
|
||||||
trace!("Path resulted in no snapshot being generated.");
|
trace!("Path resulted in no snapshot being generated.");
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
Err(err) => {
|
||||||
|
show_snapshot_error(&path_to_snapshot, err);
|
||||||
|
return;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("Snapshot: {:#?}", snapshot);
|
trace!("Snapshot: {:#?}", snapshot);
|
||||||
@@ -243,12 +260,13 @@ impl RbxSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn construct_oneoff_tree(project: &Project, imfs: &Imfs) -> RbxTree {
|
pub fn construct_oneoff_tree(project: &Project, imfs: &Imfs) -> Result<RbxTree, SnapshotError> {
|
||||||
let mut instances_per_path = PathMap::new();
|
let mut instances_per_path = PathMap::new();
|
||||||
let mut metadata_per_instance = HashMap::new();
|
let mut metadata_per_instance = HashMap::new();
|
||||||
let context = SnapshotContext {
|
let context = SnapshotContext {
|
||||||
plugin_context: None,
|
plugin_context: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
reify_initial_tree(project, &context, imfs, &mut instances_per_path, &mut metadata_per_instance)
|
reify_initial_tree(project, &context, imfs, &mut instances_per_path, &mut metadata_per_instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,13 +276,14 @@ fn reify_initial_tree(
|
|||||||
imfs: &Imfs,
|
imfs: &Imfs,
|
||||||
instances_per_path: &mut PathMap<HashSet<RbxId>>,
|
instances_per_path: &mut PathMap<HashSet<RbxId>>,
|
||||||
metadata_per_instance: &mut HashMap<RbxId, MetadataPerInstance>,
|
metadata_per_instance: &mut HashMap<RbxId, MetadataPerInstance>,
|
||||||
) -> RbxTree {
|
) -> Result<RbxTree, SnapshotError> {
|
||||||
let snapshot = snapshot_project_tree(&context, imfs, project)
|
let snapshot = match snapshot_project_tree(&context, imfs, project)? {
|
||||||
.expect("Could not snapshot project tree")
|
Some(snapshot) => snapshot,
|
||||||
.expect("Project did not produce any instances");
|
None => panic!("Project did not produce any instances"),
|
||||||
|
};
|
||||||
|
|
||||||
let mut changes = InstanceChanges::default();
|
let mut changes = InstanceChanges::default();
|
||||||
let tree = reify_root(&snapshot, instances_per_path, metadata_per_instance, &mut changes);
|
let tree = reify_root(&snapshot, instances_per_path, metadata_per_instance, &mut changes);
|
||||||
|
|
||||||
tree
|
Ok(tree)
|
||||||
}
|
}
|
||||||
6
test-projects/malformed-stuff/default.project.json
Normal file
6
test-projects/malformed-stuff/default.project.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "malformed-stuff",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
2
test-projects/malformed-stuff/src/bad-model.model.json
Normal file
2
test-projects/malformed-stuff/src/bad-model.model.json
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ahhh this isn't a JSON model
|
||||||
|
bamboozled again
|
||||||
Reference in New Issue
Block a user