22// © Copyright 2024, by Marco Mengelkoch
33// Licensed under MIT License, see License file for more details
44// git clone https://github.com/marcomq/tauri-plugin-python
5+ use async_py:: PyRunnerError ;
56
6- #[ cfg( feature = "pyo3" ) ]
7- use pyo3:: { prelude:: * , PyErr } ;
87use serde:: { ser:: Serializer , Serialize } ;
98
109pub type Result < T > = std:: result:: Result < T , Error > ;
@@ -18,6 +17,8 @@ pub enum Error {
1817 #[ cfg( mobile) ]
1918 #[ error( transparent) ]
2019 PluginInvoke ( #[ from] tauri:: plugin:: mobile:: PluginInvokeError ) ,
20+ #[ error( transparent) ]
21+ PyRunner ( #[ from] PyRunnerError ) ,
2122}
2223
2324impl Serialize for Error {
@@ -35,126 +36,6 @@ impl From<&str> for Error {
3536 }
3637}
3738
38- #[ cfg( not( feature = "pyo3" ) ) ]
39- impl From < rustpython_vm:: PyRef < rustpython_vm:: builtins:: PyBaseException > > for Error {
40- fn from ( error : rustpython_vm:: PyRef < rustpython_vm:: builtins:: PyBaseException > ) -> Self {
41- let msg = format ! ( "{:?}" , & error) ;
42- println ! ( "error: {}" , & msg) ;
43- if let Some ( tb) = error. traceback ( ) {
44- println ! ( "Traceback (most recent call last):" ) ;
45- for trace in tb. iter ( ) {
46- let file = trace. frame . code . source_path . as_str ( ) ;
47- let original_line = trace. lineno . to_usize ( ) ;
48- let line = if file == "main.py" {
49- original_line - 2 // sys.path import has 2 additional lines
50- } else {
51- original_line
52- } ;
53- println ! (
54- " File \" {file}\" , line {line}, in {}" ,
55- trace. frame. code. obj_name
56- ) ;
57- }
58- }
59- Error :: String ( msg)
60- }
61- }
62-
63- #[ cfg( feature = "pyo3" ) ]
64- impl From < PyErr > for Error {
65- fn from ( error : PyErr ) -> Self {
66- let error_msg = match pyo3:: Python :: with_gil ( |py| -> Result < Vec < String > > {
67- let traceback_module = py. import ( "traceback" ) ?;
68- let traceback_object = error
69- . traceback ( py)
70- . ok_or ( pyo3:: exceptions:: PyWarning :: new_err ( "No traceback found." ) ) ?;
71- let extract_traceback = traceback_module. getattr ( "extract_tb" ) ?;
72-
73- // Get the formatted traceback lines
74- let result = extract_traceback. call1 ( ( traceback_object, ) ) . and_then ( |r| {
75- match r. extract :: < Vec < PyObject > > ( ) {
76- Ok ( v) => {
77- let mut formatted_lines = Vec :: new ( ) ;
78- for arg in v. iter ( ) {
79- let frame = arg. bind ( py) ;
80-
81- // Extract filename
82- let filename = match frame. getattr ( "filename" ) {
83- Ok ( f) => match f. extract :: < String > ( ) {
84- Ok ( s) if s == "<string>" . to_string ( ) => {
85- // Special handling for <string>
86- frame. setattr ( "filename" , "main.py" ) ?;
87- let lineno = frame. getattr ( "lineno" ) ?. extract :: < usize > ( ) ?;
88- frame. setattr ( "lineno" , lineno - 2 ) ?;
89- "main.py" . to_string ( )
90- }
91- Ok ( s) => s,
92- Err ( _) => "<unknown>" . to_string ( ) ,
93- } ,
94- Err ( _) => "<unknown>" . to_string ( ) ,
95- } ;
96-
97- // Extract line number
98- let lineno = match frame. getattr ( "lineno" ) {
99- Ok ( l) => match l. extract :: < usize > ( ) {
100- Ok ( n) => n,
101- Err ( _) => 0 ,
102- } ,
103- Err ( _) => 0 ,
104- } ;
105-
106- // Extract function name
107- let name = match frame. getattr ( "name" ) {
108- Ok ( n) => match n. extract :: < String > ( ) {
109- Ok ( s) => s,
110- Err ( _) => "<unknown>" . to_string ( ) ,
111- } ,
112- Err ( _) => "<unknown>" . to_string ( ) ,
113- } ;
114-
115- // Extract line content (if available)
116- let line = match frame. getattr ( "line" ) {
117- Ok ( l) => match l. extract :: < Option < String > > ( ) {
118- Ok ( Some ( s) ) => format ! ( "\t {}" , s) ,
119- _ => "" . to_string ( ) ,
120- } ,
121- Err ( _) => "" . to_string ( ) ,
122- } ;
123-
124- // Format the line like requested
125- let formatted_line = format ! (
126- "File \" {}\" , line {}, in {}\n {}" ,
127- filename, lineno, name, line
128- ) ;
129-
130- formatted_lines. push ( formatted_line) ;
131- }
132-
133- Ok ( formatted_lines)
134- }
135- Err ( _) => Err ( PyErr :: new :: < pyo3:: exceptions:: PyValueError , _ > (
136- "Failed to extract traceback" ,
137- ) ) ,
138- }
139- } ) ?;
140-
141- // Add traceback header
142- let mut full_traceback = vec ! [ "Traceback (most recent call last):" . to_string( ) ] ;
143- full_traceback. extend ( result) ;
144-
145- // Add error type and message
146- full_traceback. push ( error. to_string ( ) ) ;
147-
148- Ok ( full_traceback)
149- } ) {
150- Ok ( formatted) => formatted. join ( "\n " ) ,
151- Err ( _) => error. to_string ( ) , // Fall back to simple error message
152- } ;
153-
154- Error :: String ( error_msg)
155- }
156- }
157-
15839impl From < tauri:: Error > for Error {
15940 fn from ( error : tauri:: Error ) -> Self {
16041 Error :: String ( error. to_string ( ) )
0 commit comments