Implement proper error handlign in spawned tasks
This commit is contained in:
98
src/main.rs
98
src/main.rs
@@ -40,6 +40,22 @@ fn panic_cb(panic: &panic::PanicHookInfo) {
|
||||
);
|
||||
}
|
||||
|
||||
fn error_cb(err: &luajit::Error) {
|
||||
match err.trace() {
|
||||
Some(trace) => eprintln!("{}\n{trace}", err.red().bold()),
|
||||
None => eprintln!("{}", err.red().bold()),
|
||||
}
|
||||
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
fn unwrap_exit<T, E: Display>(code: ExitCode) -> impl FnOnce(E) -> T {
|
||||
move |err| {
|
||||
eprintln!("{}", err.red().bold());
|
||||
code.exit()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct Args {
|
||||
/// Paths to scripts to execute.
|
||||
@@ -121,12 +137,12 @@ impl Args {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<(), ExitCode> {
|
||||
panic::set_hook(Box::new(panic_cb));
|
||||
|
||||
let args = Args::parse();
|
||||
if args.version {
|
||||
return print_version();
|
||||
return Ok(print_version());
|
||||
}
|
||||
|
||||
init_logger(&args);
|
||||
@@ -153,13 +169,6 @@ fn print_version() {
|
||||
);
|
||||
}
|
||||
|
||||
fn unwrap_exit<T, E: Display>(code: ExitCode) -> impl FnOnce(E) -> T {
|
||||
move |err| {
|
||||
eprintln!("{}", err.red().bold());
|
||||
code.exit()
|
||||
}
|
||||
}
|
||||
|
||||
fn init_logger(args: &Args) {
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::util::*;
|
||||
@@ -192,54 +201,62 @@ fn init_logger(args: &Args) {
|
||||
}
|
||||
|
||||
fn init_tokio(args: &Args) -> tokio::runtime::Runtime {
|
||||
let mut rt = match args.threads.get() {
|
||||
match args.threads.get() {
|
||||
1 => tokio::runtime::Builder::new_current_thread(),
|
||||
n => {
|
||||
let mut rt = tokio::runtime::Builder::new_multi_thread();
|
||||
rt.worker_threads(n - 1);
|
||||
rt
|
||||
}
|
||||
};
|
||||
|
||||
rt.enable_all()
|
||||
.thread_name("luby")
|
||||
.max_blocking_threads(args.blocking_threads.get())
|
||||
.build()
|
||||
.unwrap_or_else(unwrap_exit(ExitCode::OsErr))
|
||||
}
|
||||
.enable_all()
|
||||
.thread_name("luby")
|
||||
.max_blocking_threads(args.blocking_threads.get())
|
||||
.build()
|
||||
.unwrap_or_else(unwrap_exit(ExitCode::OsErr))
|
||||
}
|
||||
|
||||
fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
||||
let mut rt = lb::runtime::Builder::new();
|
||||
luby::open(&mut rt);
|
||||
let mut rt = {
|
||||
let mut rt = lb::runtime::Builder::new();
|
||||
rt.unhandled_error(error_cb);
|
||||
luby::open(&mut rt);
|
||||
|
||||
if args.dump.iter().find(|s| *s == "cdef").is_some() {
|
||||
print!("{}", rt.registry());
|
||||
if args.dump.iter().find(|s| *s == "cdef").is_some() {
|
||||
print!("{}", rt.registry()); // for debugging
|
||||
}
|
||||
|
||||
rt
|
||||
}
|
||||
|
||||
let mut rt = rt.build().unwrap();
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
for arg in args.jit.iter() {
|
||||
let mut s = rt.guard();
|
||||
if let Some((cmd, flags)) = parse_jitlib_cmd(arg)
|
||||
let res = if let Some((cmd, flags)) = parse_jitlib_cmd(arg)
|
||||
&& let Ok(_) = s.require(format!("jit.{cmd}"), 1)
|
||||
{
|
||||
(s.push("start"), s.get(-2), s.push(flags));
|
||||
s.call(1, 0)
|
||||
s.call(1, 0) // require("jit.{cmd}").start(flags)
|
||||
} else {
|
||||
s.require("jit", 1).unwrap();
|
||||
match arg.as_str() {
|
||||
cmd @ ("on" | "off" | "flush") => {
|
||||
(s.push(cmd), s.get(-2));
|
||||
s.call(0, 0)
|
||||
s.call(0, 0) // require("jit").[on/off/flush]()
|
||||
}
|
||||
arg => {
|
||||
flags => {
|
||||
(s.push("opt"), s.get(-2));
|
||||
(s.push("start"), s.get(-2), s.push(arg));
|
||||
s.call(1, 0)
|
||||
(s.push("start"), s.get(-2), s.push(flags));
|
||||
s.call(1, 0) // require("jit").opt.start(flags)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(err) = res {
|
||||
drop(s);
|
||||
rt.report_error(&err);
|
||||
}
|
||||
.unwrap_or_else(unwrap_exit(ExitCode::Usage));
|
||||
}
|
||||
|
||||
rt
|
||||
@@ -254,27 +271,22 @@ fn parse_jitlib_cmd(s: &str) -> Option<(&str, &str)> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn main_async(args: Args, state: &mut luajit::State) {
|
||||
async fn main_async(args: Args, cx: &mut lb::runtime::Context) -> Result<(), ExitCode> {
|
||||
for ref path in args.path {
|
||||
let mut s = state.guard();
|
||||
let chunk = match std::fs::read(path) {
|
||||
Ok(chunk) => chunk,
|
||||
Err(err) => {
|
||||
eprintln!("{}", format_args!("{path}: {err}").red().bold());
|
||||
ExitCode::NoInput.exit();
|
||||
return Err(ExitCode::NoInput);
|
||||
}
|
||||
};
|
||||
|
||||
s.load(&luajit::Chunk::new(chunk).path(path))
|
||||
.unwrap_or_else(unwrap_exit(ExitCode::NoInput));
|
||||
|
||||
if let Err(err) = s.call_async(0, 0).await {
|
||||
match err.trace() {
|
||||
Some(trace) => eprintln!("{}\n{trace}", err.red().bold()),
|
||||
None => eprintln!("{}", err.red().bold()),
|
||||
}
|
||||
|
||||
process::exit(1);
|
||||
if let Err(err) = cx.load(&luajit::Chunk::new(chunk).path(path)) {
|
||||
cx.report_error(&err);
|
||||
} else if let Err(err) = cx.call_async(0, 0).await {
|
||||
cx.report_error(&err);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user