Skip to content

Commit b7f6905

Browse files
author
zach
authored
cleanup: improve error handling (#53)
1 parent 09e4604 commit b7f6905

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

lib/src/lib.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use pyo3::types::{PyModule, PyTuple};
1+
use pyo3::types::{PyModule, PyTuple, PyTracebackMethods};
22
use pyo3::{append_to_inittab, conversion::ToPyObject, prelude::*, Py, PyAny, PyResult, Python};
33

44
mod py_module;
@@ -15,12 +15,43 @@ fn convert_arg(py: Python, arg: Arg) -> PyObject {
1515
}
1616
}
1717

18+
fn wrap_gil<T, F: FnOnce(Python) -> PyResult<T>>(err: T, f: F) -> T {
19+
let result = Python::with_gil(|py| {
20+
f(py).map_err(|err| {
21+
let tb = err.traceback_bound(py).and_then(|x|{
22+
if let Ok(x) = x.format() {
23+
Some(x)
24+
} else {
25+
None
26+
}
27+
});
28+
let mut s = err.into_value(py).to_string();
29+
if let Some(tb) = tb {
30+
s += "\n";
31+
s += &tb;
32+
}
33+
s
34+
})
35+
});
36+
match result {
37+
Ok(x) => x,
38+
Err(error) => {
39+
let mem = extism_pdk::Memory::from_bytes(&error)
40+
.expect("Load Python error message into Extism memory");
41+
unsafe {
42+
extism_pdk::extism::error_set(mem.offset());
43+
}
44+
err
45+
}
46+
}
47+
}
48+
1849
#[no_mangle]
1950
pub extern "C" fn __invoke(index: u32, shared: bool) {
20-
Python::with_gil(|py| -> PyResult<()> {
51+
wrap_gil((), |py| {
2152
let call_args = unsafe { CALL_ARGS.pop() };
2253
let mut args: Vec<PyObject> = call_args
23-
.unwrap()
54+
.unwrap()
2455
.into_iter()
2556
.map(|x| convert_arg(py, x))
2657
.collect();
@@ -31,13 +62,12 @@ pub extern "C" fn __invoke(index: u32, shared: bool) {
3162
let fun: Py<PyAny> = m.getattr("__invoke")?.into();
3263
fun.call1(py, args)?;
3364
Ok(())
34-
})
35-
.unwrap()
65+
});
3666
}
3767

3868
#[no_mangle]
3969
pub extern "C" fn __invoke_i32(index: u32, shared: bool) -> i32 {
40-
Python::with_gil(|py| -> PyResult<i32> {
70+
wrap_gil(-1, |py| -> PyResult<i32> {
4171
let call_args = unsafe { CALL_ARGS.pop() };
4272
let mut args: Vec<PyObject> = call_args
4373
.unwrap()
@@ -55,12 +85,11 @@ pub extern "C" fn __invoke_i32(index: u32, shared: bool) -> i32 {
5585
}
5686
Ok(0)
5787
})
58-
.unwrap()
5988
}
6089

6190
#[no_mangle]
6291
pub extern "C" fn __invoke_i64(index: u32, shared: bool) -> i64 {
63-
Python::with_gil(|py| -> PyResult<i64> {
92+
wrap_gil(-1, |py| -> PyResult<i64> {
6493
let call_args = unsafe { CALL_ARGS.pop() };
6594
let mut args: Vec<PyObject> = call_args
6695
.unwrap()
@@ -77,8 +106,7 @@ pub extern "C" fn __invoke_i64(index: u32, shared: bool) -> i64 {
77106
return Ok(res);
78107
}
79108
Ok(0)
80-
})
81-
.unwrap()
109+
}).into()
82110
}
83111

84112
enum Arg {

0 commit comments

Comments
 (0)