@@ -5,12 +5,14 @@ use std::fmt;
5
5
use std:: io;
6
6
use std:: io:: { Error , ErrorKind , Result } ;
7
7
use std:: mem;
8
+ use std:: ffi:: CString ;
8
9
9
10
use crate :: utils:: elog:: * ;
10
11
use crate :: utils:: memutils:: * ;
11
12
use crate :: utils:: memutils:: c:: * ;
12
13
use crate :: utils:: palloc:: * ;
13
14
15
+ #[ derive( Clone , Copy ) ]
14
16
pub enum PanicType {
15
17
ReThrow ,
16
18
Errfinish ,
@@ -55,8 +57,8 @@ macro_rules! longjmp_panic {
55
57
unsafe {
56
58
use postgres_extension:: utils:: elog
57
59
:: { PG_exception_stack ,
58
- error_context_stack,
59
- PanicReThrow } ;
60
+ error_context_stack} ;
61
+ use postgres_extension :: rust_utils :: PanicType ;
60
62
use postgres_extension:: setjmp:: { sigsetjmp, sigjmp_buf} ;
61
63
let save_exception_stack: * mut sigjmp_buf = PG_exception_stack ;
62
64
let save_context_stack: * mut ErrorContextCallback = error_context_stack;
@@ -67,7 +69,7 @@ macro_rules! longjmp_panic {
67
69
} else {
68
70
PG_exception_stack = save_exception_stack;
69
71
error_context_stack = save_context_stack;
70
- panic!( PanicReThrow ) ;
72
+ panic!( PanicType :: ReThrow ) ;
71
73
}
72
74
PG_exception_stack = save_exception_stack;
73
75
error_context_stack = save_context_stack;
@@ -94,39 +96,37 @@ pub fn init_error_handling() {
94
96
}
95
97
}
96
98
97
- pub fn handle_panic ( panic_payload : Box < dyn std:: any:: Any > ) -> PanicType {
98
- if panic_payload. is :: < PanicReThrow > ( ) {
99
- PanicType :: ReThrow
100
- } else if panic_payload. is :: < PanicErrfinish > ( ) {
101
- PanicType :: Errfinish
102
- } else {
103
- use std:: ffi:: CString ;
104
-
105
- let panic_message =
106
- if let Some ( err_str) = panic_payload. downcast_ref :: < & str > ( ) {
107
- format ! ( "{}" , err_str)
108
- } else {
109
- format ! ( "{:?}" , panic_payload)
110
- } ;
99
+ pub fn handle_panic ( payload : Box < dyn std:: any:: Any > ) -> PanicType {
100
+ if let Some ( panictype) = payload. downcast_ref :: < PanicType > ( ) {
101
+ return * panictype
102
+ }
111
103
112
- let message = format ! ( "rust panic: {}" , panic_message) ;
113
- let hint = "find out what rust code caused the panic" ;
114
- let detail = "some rust code caused a panic" ;
104
+ let panic_message =
105
+ if let Some ( s) = payload. downcast_ref :: < & str > ( ) {
106
+ s
107
+ } else if let Some ( s) = payload. downcast_ref :: < String > ( ) {
108
+ & s[ ..]
109
+ } else {
110
+ "Box<Any>"
111
+ } ;
115
112
116
- let cmessage = CString :: new ( message . as_str ( ) ) . unwrap ( ) ;
117
- let chint = CString :: new ( hint ) . unwrap ( ) ;
118
- let cdetail = CString :: new ( detail ) . unwrap ( ) ;
113
+ let message = format ! ( "rust panic: {}" , panic_message ) ;
114
+ let hint = "find out what rust code caused the panic" ;
115
+ let detail = "some rust code caused a panic" ;
119
116
120
- unsafe {
121
- pg_errstart ( ERROR , file ! ( ) , line ! ( ) ) ;
122
- errcode ( ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ) ;
123
- errmsg ( cmessage. as_ptr ( ) ) ;
124
- errhint ( chint. as_ptr ( ) ) ;
125
- errdetail ( cdetail. as_ptr ( ) ) ;
126
- }
117
+ let cmessage = CString :: new ( message. as_str ( ) ) . unwrap ( ) ;
118
+ let chint = CString :: new ( hint) . unwrap ( ) ;
119
+ let cdetail = CString :: new ( detail) . unwrap ( ) ;
127
120
128
- PanicType :: Errfinish
121
+ unsafe {
122
+ pg_errstart ( ERROR , file ! ( ) , line ! ( ) ) ;
123
+ errcode ( ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ) ;
124
+ errmsg ( cmessage. as_ptr ( ) ) ;
125
+ errhint ( chint. as_ptr ( ) ) ;
126
+ errdetail ( cdetail. as_ptr ( ) ) ;
129
127
}
128
+
129
+ PanicType :: Errfinish
130
130
}
131
131
132
132
// implement Write trait for &[i8] (a.k.a. &[c_char])
0 commit comments