1
+ use super :: obj:: objlist;
1
2
use super :: obj:: objstr;
3
+ use super :: obj:: objtuple;
4
+ use super :: obj:: objtype;
2
5
use super :: pyobject:: {
3
- create_type, AttributeProtocol , PyContext , PyFuncArgs , PyObjectRef , PyResult ,
6
+ create_type, AttributeProtocol , PyContext , PyFuncArgs , PyObjectRef , PyResult , TypeProtocol ,
4
7
} ;
5
8
use super :: vm:: VirtualMachine ;
6
9
@@ -17,13 +20,59 @@ fn exception_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
17
20
Ok ( vm. get_none ( ) )
18
21
}
19
22
23
+ // Print exception including traceback:
20
24
pub fn print_exception ( vm : & mut VirtualMachine , exc : & PyObjectRef ) {
25
+ if let Some ( tb) = exc. get_attr ( "__traceback__" ) {
26
+ println ! ( "Traceback (most recent call last):" ) ;
27
+ if objtype:: isinstance ( tb. clone ( ) , vm. ctx . list_type ( ) ) {
28
+ let elements = objlist:: get_elements ( & tb) ;
29
+ for element in elements {
30
+ if objtype:: isinstance ( element. clone ( ) , vm. ctx . tuple_type ( ) ) {
31
+ let element = objtuple:: get_elements ( & element) ;
32
+ let filename = if let Ok ( x) = vm. to_str ( element[ 0 ] . clone ( ) ) {
33
+ objstr:: get_value ( & x)
34
+ } else {
35
+ "<error>" . to_string ( )
36
+ } ;
37
+
38
+ let lineno = if let Ok ( x) = vm. to_str ( element[ 1 ] . clone ( ) ) {
39
+ objstr:: get_value ( & x)
40
+ } else {
41
+ "<error>" . to_string ( )
42
+ } ;
43
+
44
+ println ! ( " File {}, line {}, in .." , filename, lineno) ;
45
+ } else {
46
+ println ! ( " File ??" ) ;
47
+ }
48
+ }
49
+ }
50
+ } else {
51
+ println ! ( "No traceback set on exception" ) ;
52
+ }
53
+
21
54
match vm. to_str ( exc. clone ( ) ) {
22
- Ok ( txt) => println ! ( "Error: {}" , objstr:: get_value( & txt) ) ,
55
+ Ok ( txt) => println ! ( "{}" , objstr:: get_value( & txt) ) ,
23
56
Err ( err) => println ! ( "Error during error {:?}" , err) ,
24
57
}
25
58
}
26
59
60
+ fn exception_str ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
61
+ arg_check ! (
62
+ vm,
63
+ args,
64
+ required = [ ( exc, Some ( vm. ctx. exceptions. exception_type. clone( ) ) ) ]
65
+ ) ;
66
+ let type_name = objtype:: get_type_name ( & exc. typ ( ) ) ;
67
+ let msg = if let Some ( m) = exc. get_attr ( "__msg__" ) {
68
+ objstr:: get_value ( & m)
69
+ } else {
70
+ panic ! ( "Error message must be set" ) ;
71
+ } ;
72
+ let s = format ! ( "{}: {}" , type_name, msg) ;
73
+ Ok ( vm. new_str ( s) )
74
+ }
75
+
27
76
#[ derive( Debug ) ]
28
77
pub struct ExceptionZoo {
29
78
pub base_exception_type : PyObjectRef ,
@@ -112,6 +161,6 @@ impl ExceptionZoo {
112
161
pub fn init ( context : & PyContext ) {
113
162
let ref base_exception_type = context. exceptions . base_exception_type ;
114
163
base_exception_type. set_attr ( "__init__" , context. new_rustfunc ( exception_init) ) ;
115
-
116
- // TODO: create a whole exception hierarchy somehow?
164
+ let ref exception_type = context . exceptions . exception_type ;
165
+ exception_type . set_attr ( "__str__" , context . new_rustfunc ( exception_str ) ) ;
117
166
}
0 commit comments