mirror of
https://github.com/CompeyDev/lune-packaging.git
synced 2025-01-09 12:19:09 +00:00
Improve general error message formatting
This commit is contained in:
parent
8e168d3a9d
commit
99ca1fc230
7 changed files with 97 additions and 19 deletions
|
@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Changed
|
||||
|
||||
- Improved error messages for passing invalid file names / file paths substantially - they now include helpful formatting to make file names distinct from file extensions, and give suggestions on how to solve the problem
|
||||
- Improved general formatting of error messages, both in the CLI and for Luau scripts being run
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -175,11 +175,13 @@ impl Cli {
|
|||
(file_display_name, file_contents)
|
||||
};
|
||||
// Create a new lune object with all globals & run the script
|
||||
let lune = Lune::new().with_args(self.script_args);
|
||||
let result = lune.run(&script_display_name, &script_contents).await;
|
||||
let result = Lune::new()
|
||||
.with_args(self.script_args)
|
||||
.try_run(&script_display_name, &script_contents)
|
||||
.await;
|
||||
Ok(match result {
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
Ok(code) => code,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
use std::process::ExitCode;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
|
||||
pub(crate) mod cli;
|
||||
|
@ -21,8 +20,20 @@ pub(crate) mod utils;
|
|||
mod tests;
|
||||
|
||||
use cli::Cli;
|
||||
use console::style;
|
||||
|
||||
#[tokio::main(flavor = "multi_thread")]
|
||||
async fn main() -> Result<ExitCode> {
|
||||
Cli::parse().run().await
|
||||
async fn main() -> ExitCode {
|
||||
match Cli::parse().run().await {
|
||||
Ok(code) => code,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"{}{}{}\n{err:?}",
|
||||
style("[").dim(),
|
||||
style("ERROR").red(),
|
||||
style("]").dim(),
|
||||
);
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
39
packages/lib/src/error.rs
Normal file
39
packages/lib/src/error.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use std::{
|
||||
error::Error,
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
};
|
||||
|
||||
use mlua::prelude::*;
|
||||
|
||||
use crate::lua::stdio::formatting::pretty_format_luau_error;
|
||||
|
||||
/**
|
||||
An opaque error type for formatted lua errors.
|
||||
*/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LuneError {
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl LuneError {
|
||||
pub(crate) fn new(message: String) -> Self {
|
||||
Self { message }
|
||||
}
|
||||
|
||||
pub(crate) fn from_lua_error(error: LuaError) -> Self {
|
||||
Self::new(pretty_format_luau_error(&error, true))
|
||||
}
|
||||
|
||||
pub(crate) fn from_lua_error_plain(error: LuaError) -> Self {
|
||||
Self::new(pretty_format_luau_error(&error, false))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for LuneError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "{}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for LuneError {}
|
|
@ -7,14 +7,14 @@ use tokio::task::LocalSet;
|
|||
pub(crate) mod globals;
|
||||
pub(crate) mod lua;
|
||||
|
||||
mod error;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use error::LuneError;
|
||||
pub use globals::LuneGlobal;
|
||||
pub use lua::create_lune_lua;
|
||||
|
||||
use lua::stdio::formatting::pretty_format_luau_error;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Lune {
|
||||
args: Vec<String>,
|
||||
|
@ -52,24 +52,45 @@ impl Lune {
|
|||
both live for the remainer of the program, and that this leaks memory using
|
||||
[`Box::leak`] that will then get deallocated when the program exits.
|
||||
*/
|
||||
pub async fn try_run(
|
||||
&self,
|
||||
script_name: impl AsRef<str>,
|
||||
script_contents: impl AsRef<[u8]>,
|
||||
) -> Result<ExitCode, LuneError> {
|
||||
self.run(script_name, script_contents, true)
|
||||
.await
|
||||
.map_err(LuneError::from_lua_error)
|
||||
}
|
||||
|
||||
/**
|
||||
Tries to run a Lune script directly, returning the underlying
|
||||
result type if loading the script raises a lua error.
|
||||
|
||||
Passing `false` as the third argument `emit_prettified_errors` will
|
||||
bypass any additional error formatting automatically done by Lune
|
||||
for errors that are emitted while the script is running.
|
||||
|
||||
Behavior is otherwise exactly the same as `try_run`
|
||||
and `try_run` should be preferred in all other cases.
|
||||
*/
|
||||
#[doc(hidden)]
|
||||
pub async fn run(
|
||||
&self,
|
||||
script_name: impl AsRef<str>,
|
||||
script_contents: impl AsRef<[u8]>,
|
||||
emit_prettified_errors: bool,
|
||||
) -> Result<ExitCode, LuaError> {
|
||||
// Create our special lune-flavored Lua object with extra registry values
|
||||
let lua = create_lune_lua().expect("Failed to create Lua object");
|
||||
let lua = create_lune_lua()?;
|
||||
// Create our task scheduler
|
||||
let sched = TaskScheduler::new(lua)?.into_static();
|
||||
lua.set_app_data(sched);
|
||||
// Create the main thread and schedule it
|
||||
let main_chunk = lua
|
||||
.load(script_contents.as_ref())
|
||||
.set_name(script_name.as_ref())
|
||||
.unwrap()
|
||||
.into_function()
|
||||
.unwrap();
|
||||
let main_thread = lua.create_thread(main_chunk).unwrap();
|
||||
.set_name(script_name.as_ref())?
|
||||
.into_function()?;
|
||||
let main_thread = lua.create_thread(main_chunk)?;
|
||||
let main_thread_args = LuaValue::Nil.to_lua_multi(lua)?;
|
||||
sched.schedule_blocking(main_thread, main_thread_args)?;
|
||||
// Create our wanted lune globals, some of these need
|
||||
|
@ -85,7 +106,11 @@ impl Lune {
|
|||
loop {
|
||||
let result = sched.resume_queue().await;
|
||||
if let Some(err) = result.get_lua_error() {
|
||||
eprintln!("{}", pretty_format_luau_error(&err, true));
|
||||
if emit_prettified_errors {
|
||||
eprintln!("{}", LuneError::from_lua_error(err));
|
||||
} else {
|
||||
eprintln!("{err}");
|
||||
}
|
||||
got_error = true;
|
||||
}
|
||||
if result.is_done() {
|
||||
|
|
|
@ -40,14 +40,14 @@ fn can_be_plain_lua_table_key(s: &LuaString) -> bool {
|
|||
pub fn format_label<S: AsRef<str>>(s: S) -> String {
|
||||
format!(
|
||||
"{}{}{} ",
|
||||
style("[").bold(),
|
||||
style("[").dim(),
|
||||
match s.as_ref().to_ascii_lowercase().as_str() {
|
||||
"info" => style("INFO").blue(),
|
||||
"warn" => style("WARN").yellow(),
|
||||
"error" => style("ERROR").red(),
|
||||
_ => style(""),
|
||||
},
|
||||
style("]").bold()
|
||||
style("]").dim()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ macro_rules! create_tests {
|
|||
.trim_end_matches(".luau")
|
||||
.trim_end_matches(".lua")
|
||||
.to_string();
|
||||
let exit_code = lune.run(&script_name, &script).await?;
|
||||
let exit_code = lune.try_run(&script_name, &script).await?;
|
||||
Ok(exit_code)
|
||||
}
|
||||
)* }
|
||||
|
|
Loading…
Reference in a new issue