Skip to content

Commit 18baaf8

Browse files
authored
Merge pull request #5 from Icemic/module_loader_result
Better error handling of module loader
2 parents 88e8b20 + 4fd8ee4 commit 18baaf8

File tree

4 files changed

+42
-17
lines changed

4 files changed

+42
-17
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ repository = "https://github.com/Icemic/quickjs-rusty"
1111
version = "0.7.0"
1212

1313
[package.metadata.docs.rs]
14-
features = ["chrono", "bigint", "log"]
14+
features = ["chrono", "bigint"]
1515

1616
[features]
1717
bigint = ["num-bigint", "num-traits"]
@@ -22,7 +22,7 @@ serde = ["thiserror", "dep:serde"]
2222
anyhow = {version = "1"}
2323
chrono = {version = "0.4.7", optional = true}
2424
libquickjs-ng-sys = {version = "^0.7.1", path = "./libquickjs-sys"}
25-
log = {version = "0.4.8", optional = true}
25+
log = "0.4"
2626
num-bigint = {version = "0.4.4", optional = true}
2727
num-traits = {version = "0.2.0", optional = true}
2828
serde = {version = "1", features = ["derive"], optional = true}

examples/eval_module.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::Result;
12
use quickjs_rusty::Context;
23

34
struct Custom {
@@ -31,20 +32,20 @@ pub fn main() {
3132
println!("js: 1 + 2 = {:?}", value);
3233
}
3334

34-
fn module_loader(module_name: &str, opaque: *mut std::ffi::c_void) -> String {
35+
fn module_loader(module_name: &str, opaque: *mut std::ffi::c_void) -> Result<String> {
3536
println!("module_loader: {:?}", module_name);
3637
let custom = unsafe { &*(opaque as *mut Custom) };
3738
assert!(custom.foo == 123);
38-
"export function add(a, b) { return a + b; }; console.log('module loaded.')".to_string()
39+
Ok("export function add(a, b) { return a + b; }; console.log('module loaded.')".to_string())
3940
}
4041

4142
fn module_normalize(
4243
module_base_name: &str,
4344
module_name: &str,
4445
opaque: *mut std::ffi::c_void,
45-
) -> String {
46+
) -> Result<String> {
4647
println!("module_normalize: {:?} {:?}", module_base_name, module_name);
4748
let custom = unsafe { &*(opaque as *mut Custom) };
4849
assert!(custom.foo == 123);
49-
module_name.to_string()
50+
Ok(module_name.to_string())
5051
}

src/errors/execution_error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl fmt::Display for ExecutionError {
3030
Internal(e) => write!(f, "Internal error: {}", e),
3131
Exception(e) => {
3232
if e.is_string() {
33-
write!(f, "{:?}", e.to_string().unwrap())
33+
write!(f, "{}", e.to_string().unwrap())
3434
} else {
3535
write!(f, "JS Exception: {:?}", e)
3636
}

src/module_loader.rs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
use std::ffi::{c_char, c_void, CStr};
1+
use std::ffi::{c_char, c_void, CStr, CString};
22
use std::ptr::null_mut;
33

4+
use anyhow::Result;
45
use libquickjs_ng_sys as q;
56

67
use super::compile::compile_module;
78

8-
pub type JSModuleLoaderFunc = Box<dyn Fn(&str, *mut c_void) -> String>;
9-
pub type JSModuleNormalizeFunc = Box<dyn Fn(&str, &str, *mut c_void) -> String>;
9+
/// Custom module loader function, passes (module_name, opaque) and returns module code
10+
/// If the module code is not found, return None
11+
pub type JSModuleLoaderFunc = Box<dyn Fn(&str, *mut c_void) -> Result<String>>;
12+
/// Custom module normalize function, passes (module_base_name, module_name, opaque)
13+
/// and returns normalized module name (or None if not found)
14+
pub type JSModuleNormalizeFunc = Box<dyn Fn(&str, &str, *mut c_void) -> Result<String>>;
1015

1116
pub struct ModuleLoader {
1217
pub loader: JSModuleLoaderFunc,
@@ -23,17 +28,22 @@ pub unsafe extern "C" fn js_module_loader(
2328
let opaque = wrapper.opaque;
2429
let loader = &wrapper.loader;
2530

26-
let module_name = CStr::from_ptr(module_name).to_str().unwrap();
27-
let module_code = loader(module_name, opaque);
31+
let module_name = CStr::from_ptr(module_name).to_string_lossy().to_string();
32+
let module_code = match loader(&module_name, opaque) {
33+
Ok(v) => v,
34+
Err(err) => {
35+
throw_internal_error(ctx, &err.to_string());
36+
return null_mut() as *mut q::JSModuleDef;
37+
}
38+
};
2839

29-
match compile_module(ctx, &module_code, module_name) {
40+
match compile_module(ctx, &module_code, &module_name) {
3041
Ok(v) => {
3142
let module_def = q::JS_Ext_GetPtr(v.value);
32-
// q::JS_DupValue(wrapper.context, v.value);
3343
module_def as *mut q::JSModuleDef
3444
}
3545
Err(e) => {
36-
eprintln!("compile module error: {:?}", e);
46+
throw_internal_error(ctx, &e.to_string());
3747
null_mut() as *mut q::JSModuleDef
3848
}
3949
}
@@ -54,7 +64,13 @@ pub unsafe extern "C" fn js_module_normalize(
5464

5565
if let Some(module_normalize_func) = normalize {
5666
let mut normalized_module_name =
57-
module_normalize_func(module_base_name, module_name, opaque);
67+
match module_normalize_func(module_base_name, module_name, opaque) {
68+
Ok(v) => v,
69+
Err(err) => {
70+
throw_internal_error(ctx, &err.to_string());
71+
return null_mut() as *mut c_char;
72+
}
73+
};
5874
normalized_module_name.push('\0');
5975
let m = q::js_malloc(ctx, normalized_module_name.len());
6076
std::ptr::copy(
@@ -64,7 +80,15 @@ pub unsafe extern "C" fn js_module_normalize(
6480
);
6581
m as *mut c_char
6682
} else {
67-
eprintln!("module normalize func not set");
83+
log::warn!("module normalize func not set");
6884
null_mut() as *mut c_char
6985
}
7086
}
87+
88+
#[inline]
89+
fn throw_internal_error(ctx: *mut q::JSContext, err: &str) {
90+
let err = CString::new(err).unwrap();
91+
unsafe {
92+
q::JS_ThrowInternalError(ctx, err.as_ptr() as *const i8);
93+
}
94+
}

0 commit comments

Comments
 (0)