better error reporting from lua

This commit is contained in:
2025-01-22 16:38:43 +01:00
parent 36cf1c7cf2
commit 5f0e955559
3 changed files with 62 additions and 45 deletions

13
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
@@ -1436,16 +1436,17 @@ dependencies = [
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.9.9" version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" checksum = "9ea43c3ffac2d0798bd7128815212dd78c98316b299b7a902dabef13dc7b6b8d"
dependencies = [ dependencies = [
"bstr", "bstr",
"either",
"erased-serde", "erased-serde",
"futures-util", "futures-util",
"mlua-sys", "mlua-sys",
"num-traits", "num-traits",
"once_cell", "parking_lot",
"rustc-hash", "rustc-hash",
"serde", "serde",
"serde-value", "serde-value",
@@ -1453,9 +1454,9 @@ dependencies = [
[[package]] [[package]]
name = "mlua-sys" name = "mlua-sys"
version = "0.6.2" version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab7a5b4756b8177a2dfa8e0bbcde63bd4000afbc4ab20cbb68d114a25470f29" checksum = "63a11d485edf0f3f04a508615d36c7d50d299cf61a7ee6d3e2530651e0a31771"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if 1.0.0", "cfg-if 1.0.0",

View File

@@ -25,7 +25,7 @@ exe = "0.5"
image = { version = "0.25", features = ["ico"] } image = { version = "0.25", features = ["ico"] }
urlencoding = "2.1" urlencoding = "2.1"
markdown = "1.0.0-alpha.16" markdown = "1.0.0-alpha.16"
mlua = { version = "0.9", features = [ mlua = { version = "0.10", features = [
"lua54", "lua54",
"vendored", "vendored",
"serialize", "serialize",

View File

@@ -184,7 +184,7 @@ async fn file_handler(request: Request) -> impl IntoResponse {
.try_call(request) .try_call(request)
.await .await
.map(|e| e.into_response()) .map(|e| e.into_response())
.map_err(|_| StatusCode::NOT_FOUND); .map_err(|_| (StatusCode::NOT_FOUND, "404: Not Found".to_string()));
}; };
let lua = Lua::new(); let lua = Lua::new();
@@ -202,7 +202,7 @@ async fn file_handler(request: Request) -> impl IntoResponse {
}) })
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let fetch_b64 = lua let fetch_b64 = lua
@@ -216,7 +216,7 @@ async fn file_handler(request: Request) -> impl IntoResponse {
}) })
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let dbg = lua let dbg = lua
@@ -226,27 +226,27 @@ async fn file_handler(request: Request) -> impl IntoResponse {
}) })
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
globals.set("fetch", fetch_json).map_err(|e| { globals.set("fetch", fetch_json).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
globals.set("fetch_b64", fetch_b64).map_err(|e| { globals.set("fetch_b64", fetch_b64).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
globals.set("dbg", dbg).map_err(|e| { globals.set("dbg", dbg).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let request_table = lua.create_table().map_err(|e| { let request_table = lua.create_table().map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let headers_table = lua let headers_table = lua
@@ -258,37 +258,37 @@ async fn file_handler(request: Request) -> impl IntoResponse {
) )
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
request_table.set("headers", headers_table).map_err(|e| { request_table.set("headers", headers_table).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
request_table request_table
.set("uri", request.uri().to_string()) .set("uri", request.uri().to_string())
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
request_table request_table
.set("method", request.method().to_string()) .set("method", request.method().to_string())
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
// Inject functions to change headers and such // Inject functions to change headers and such
globals.set("request", request_table).map_err(|e| { globals.set("request", request_table).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let response_table = lua.create_table().map_err(|e| { let response_table = lua.create_table().map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
response_table response_table
@@ -296,83 +296,86 @@ async fn file_handler(request: Request) -> impl IntoResponse {
"headers", "headers",
lua.create_table().map_err(|e| { lua.create_table().map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?, })?,
) )
.map_err(|e| { .map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
globals.set("response", response_table).map_err(|e| { globals.set("response", response_table).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let mut path = base_dir.clone(); let mut path = base_dir.clone();
let uri = urlencoding::decode(&request.uri().path()[1..]).map_err(|e| { let uri = urlencoding::decode(&request.uri().path()[1..]).map_err(|e| {
println!("{:?}", e); println!("{:?}", e);
StatusCode::INTERNAL_SERVER_ERROR (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
})?; })?;
path.push(&*uri); path.push(&*uri);
let full_path = fs::canonicalize(&path).map_err(|e| { let full_path = fs::canonicalize(&path).map_err(|e| {
println!("{:?}", e); println!("{:?}", e);
StatusCode::NOT_FOUND (StatusCode::NOT_FOUND, "404: Not Found".to_string())
})?; })?;
let full_base_path = fs::canonicalize(base_dir).map_err(|e| { let full_base_path = fs::canonicalize(base_dir).map_err(|e| {
println!("{:?}", e); println!("{:?}", e);
StatusCode::NOT_FOUND (StatusCode::NOT_FOUND, "404: Not Found".to_string())
})?; })?;
if !full_path.starts_with(full_base_path) { if !full_path.starts_with(full_base_path) {
return Err(StatusCode::BAD_REQUEST); return Err((StatusCode::BAD_REQUEST, "400: Bad Request".to_string()));
} }
let script = fs::read_to_string(full_path).map_err(|e| { let script = fs::read_to_string(full_path).map_err(|e| {
eprintln!("Lua Read Error: {:?}", e); eprintln!("Lua Read Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
})?; })?;
let script = lua.load(script).eval::<LuaValue>().map_err(|e| { let script = lua.load(script).eval::<LuaValue>().map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let result = lua.load("return response").eval::<Table>().map_err(|e| { let result = lua.load("return response").eval::<Table>().map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
let script = if let LuaValue::String(script) = script { let script = if let LuaValue::String(script) = script {
script.to_string_lossy().to_string() script.to_string_lossy().to_string()
} else { } else {
serde_json::to_string(&script).map_err(|e| { serde_json::to_string(&script).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Serde Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR (
StatusCode::INTERNAL_SERVER_ERROR,
format!("Serde error: {}", e),
)
})? })?
}; };
let mut response = Html(script).into_response(); let mut response = Html(script).into_response();
if let Ok(headers) = result.get::<&str, Table>("headers") { if let Ok(headers) = result.get::<Table>("headers") {
let pairs = headers.pairs::<String, String>(); let pairs = headers.pairs::<String, String>();
for pair in pairs { for pair in pairs {
let (k, v) = pair.map_err(|e| { let (k, v) = pair.map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR to_lua_error(e)
})?; })?;
response.headers_mut().insert( response.headers_mut().insert(
HeaderName::from_str(&k).map_err(|e| { HeaderName::from_str(&k).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
})?, })?,
HeaderValue::from_str(&v).map_err(|e| { HeaderValue::from_str(&v).map_err(|e| {
eprintln!("Lua Error: {:?}", e); eprintln!("Lua Error: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
})?, })?,
); );
} }
@@ -381,29 +384,42 @@ async fn file_handler(request: Request) -> impl IntoResponse {
Ok(response) Ok(response)
} }
async fn handler(request: Request) -> Result<Html<String>, StatusCode> { fn to_lua_error(e: mlua::Error) -> (StatusCode, String) {
let e = e
.to_string()
.split(':')
.skip(4)
.collect::<Vec<&str>>()
.join(":");
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("LuaError on line {}", e),
)
}
async fn handler(request: Request) -> Result<Html<String>, (StatusCode, String)> {
let start = Instant::now(); let start = Instant::now();
let base_dir = BASE_DIR.get().unwrap(); let base_dir = BASE_DIR.get().unwrap();
let mut path = base_dir.clone(); let mut path = base_dir.clone();
let uri = urlencoding::decode(&request.uri().path()[1..]).map_err(|e| { let uri = urlencoding::decode(&request.uri().path()[1..]).map_err(|e| {
println!("{:?}", e); println!("{:?}", e);
StatusCode::INTERNAL_SERVER_ERROR (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
})?; })?;
path.push(&*uri); path.push(&*uri);
let full_path = fs::canonicalize(&path).map_err(|e| { let full_path = fs::canonicalize(&path).map_err(|e| {
println!("{:?}", e); println!("{:?}", e);
StatusCode::NOT_FOUND (StatusCode::NOT_FOUND, "404: Not Found".to_string())
})?; })?;
let full_base_path = fs::canonicalize(base_dir).map_err(|e| { let full_base_path = fs::canonicalize(base_dir).map_err(|e| {
println!("{:?}", e); println!("{:?}", e);
StatusCode::NOT_FOUND (StatusCode::NOT_FOUND, "404: Not Found".to_string())
})?; })?;
if !full_path.starts_with(full_base_path) { if !full_path.starts_with(full_base_path) {
return Err(StatusCode::BAD_REQUEST); return Err((StatusCode::BAD_REQUEST, "400: Bad Request".to_string()));
} }
let body = match render_dir(&path, start).await { let body = match render_dir(&path, start).await {
@@ -412,14 +428,14 @@ async fn handler(request: Request) -> Result<Html<String>, StatusCode> {
let ioerror: Option<&std::io::Error> = e.downcast_ref(); let ioerror: Option<&std::io::Error> = e.downcast_ref();
if let Some(ioerror) = ioerror { if let Some(ioerror) = ioerror {
if ioerror.kind() == ErrorKind::NotFound { if ioerror.kind() == ErrorKind::NotFound {
Err(StatusCode::NOT_FOUND) Err((StatusCode::NOT_FOUND, "404: Not Found".to_string()))
} else { } else {
println!("{:?}", ioerror); println!("{:?}", ioerror);
Err(StatusCode::INTERNAL_SERVER_ERROR) Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
} }
} else { } else {
println!("{:?}", e); println!("{:?}", e);
Err(StatusCode::INTERNAL_SERVER_ERROR) Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
} }
} }
}; };