1
1
//! A visitor for downcasting arbitrary request (JSON) into a specific type.
2
- use std:: { fmt, panic} ;
2
+ use std:: { fmt, panic, thread } ;
3
3
4
4
use serde:: { de:: DeserializeOwned , Serialize } ;
5
5
@@ -32,7 +32,7 @@ impl<'a> RequestDispatcher<'a> {
32
32
} ;
33
33
let global_state = panic:: AssertUnwindSafe ( & mut * self . global_state ) ;
34
34
35
- let response = panic:: catch_unwind ( move || {
35
+ let result = panic:: catch_unwind ( move || {
36
36
let _ = & global_state;
37
37
let panic:: AssertUnwindSafe ( global_state) = global_state;
38
38
let _pctx = stdx:: panic_context:: enter ( format ! (
@@ -41,10 +41,10 @@ impl<'a> RequestDispatcher<'a> {
41
41
R :: METHOD ,
42
42
params
43
43
) ) ;
44
- let result = f ( global_state, params) ;
45
- result_to_response :: < R > ( id , result )
46
- } )
47
- . map_err ( |_err| format ! ( "sync task {:?} panicked" , R :: METHOD ) ) ? ;
44
+ f ( global_state, params)
45
+ } ) ;
46
+ let response = result_to_response :: < R > ( id , result ) ;
47
+
48
48
self . global_state . respond ( response) ;
49
49
Ok ( self )
50
50
}
@@ -56,7 +56,7 @@ impl<'a> RequestDispatcher<'a> {
56
56
) -> & mut Self
57
57
where
58
58
R : lsp_types:: request:: Request + ' static ,
59
- R :: Params : DeserializeOwned + Send + fmt:: Debug + ' static ,
59
+ R :: Params : DeserializeOwned + panic :: UnwindSafe + Send + fmt:: Debug + ' static ,
60
60
R :: Result : Serialize + ' static ,
61
61
{
62
62
let ( id, params) = match self . parse :: < R > ( ) {
@@ -66,16 +66,18 @@ impl<'a> RequestDispatcher<'a> {
66
66
67
67
self . global_state . task_pool . handle . spawn ( {
68
68
let world = self . global_state . snapshot ( ) ;
69
-
70
69
move || {
71
- let _pctx = stdx:: panic_context:: enter ( format ! (
72
- "\n version: {}\n request: {} {:#?}" ,
73
- env!( "REV" ) ,
74
- R :: METHOD ,
75
- params
76
- ) ) ;
77
- let result = f ( world, params) ;
78
- Task :: Response ( result_to_response :: < R > ( id, result) )
70
+ let result = panic:: catch_unwind ( move || {
71
+ let _pctx = stdx:: panic_context:: enter ( format ! (
72
+ "\n version: {}\n request: {} {:#?}" ,
73
+ env!( "REV" ) ,
74
+ R :: METHOD ,
75
+ params
76
+ ) ) ;
77
+ f ( world, params)
78
+ } ) ;
79
+ let response = result_to_response :: < R > ( id, result) ;
80
+ Task :: Response ( response)
79
81
}
80
82
} ) ;
81
83
@@ -122,16 +124,16 @@ impl<'a> RequestDispatcher<'a> {
122
124
123
125
fn result_to_response < R > (
124
126
id : lsp_server:: RequestId ,
125
- result : Result < R :: Result > ,
127
+ result : thread :: Result < Result < R :: Result > > ,
126
128
) -> lsp_server:: Response
127
129
where
128
130
R : lsp_types:: request:: Request + ' static ,
129
131
R :: Params : DeserializeOwned + ' static ,
130
132
R :: Result : Serialize + ' static ,
131
133
{
132
134
match result {
133
- Ok ( resp) => lsp_server:: Response :: new_ok ( id, & resp) ,
134
- Err ( e) => match e. downcast :: < LspError > ( ) {
135
+ Ok ( Ok ( resp) ) => lsp_server:: Response :: new_ok ( id, & resp) ,
136
+ Ok ( Err ( e) ) => match e. downcast :: < LspError > ( ) {
135
137
Ok ( lsp_error) => lsp_server:: Response :: new_err ( id, lsp_error. code , lsp_error. message ) ,
136
138
Err ( e) => {
137
139
if is_cancelled ( & * e) {
@@ -149,6 +151,21 @@ where
149
151
}
150
152
}
151
153
} ,
154
+ Err ( panic) => {
155
+ let mut message = "server panicked" . to_string ( ) ;
156
+
157
+ let panic_message = panic
158
+ . downcast_ref :: < String > ( )
159
+ . map ( String :: as_str)
160
+ . or_else ( || panic. downcast_ref :: < & str > ( ) . copied ( ) ) ;
161
+
162
+ if let Some ( panic_message) = panic_message {
163
+ message. push_str ( ": " ) ;
164
+ message. push_str ( panic_message)
165
+ } ;
166
+
167
+ lsp_server:: Response :: new_err ( id, lsp_server:: ErrorCode :: InternalError as i32 , message)
168
+ }
152
169
}
153
170
}
154
171
0 commit comments