@@ -154,13 +154,38 @@ export class Callback {
154154 args : Deno . PointerValue ,
155155 kwargs : Deno . PointerValue ,
156156 ) => {
157- return PyObject . from ( callback (
158- kwargs === null ? { } : Object . fromEntries (
159- new PyObject ( kwargs ) . asDict ( )
160- . entries ( ) ,
161- ) ,
162- ...( args === null ? [ ] : new PyObject ( args ) . valueOf ( ) ) ,
163- ) ) . handle ;
157+ let result : PythonConvertible ;
158+ // Prepare arguments for the JS callback
159+ try {
160+ // Prepare arguments for the JS callback
161+ const jsKwargs = kwargs === null
162+ ? { }
163+ : Object . fromEntries ( new PyObject ( kwargs ) . asDict ( ) . entries ( ) ) ;
164+ const jsArgs = args === null ? [ ] : new PyObject ( args ) . valueOf ( ) ;
165+
166+ // Call the actual JS function
167+ result = callback ( jsKwargs , ...jsArgs ) ;
168+
169+ // Convert the JS return value back to a Python object
170+ return PyObject . from ( result ) . handle ;
171+ } catch ( e ) {
172+ // An error occurred in the JS callback.
173+ // We need to set a Python exception and return NULL.
174+
175+ // Prepare the error message for Python
176+ const errorMessage = e instanceof Error
177+ ? `${ e . name } : ${ e . message } ` // Include JS error type and message
178+ : String ( e ) ; // Fallback for non-Error throws
179+ const cErrorMessage = cstr ( `JS Callback Error: ${ errorMessage } ` ) ;
180+
181+ const errorTypeHandle =
182+ python . builtins . RuntimeError [ ProxiedPyObject ] . handle ;
183+
184+ // Set the Python exception (type and message)
185+ py . PyErr_SetString ( errorTypeHandle , cErrorMessage ) ;
186+
187+ return null ;
188+ }
164189 } ,
165190 ) ;
166191 }
0 commit comments