1
1
//! See [RequestDispatcher].
2
2
use std:: { fmt, panic, thread} ;
3
3
4
+ use ide:: Cancelled ;
4
5
use lsp_server:: ExtractError ;
5
6
use serde:: { de:: DeserializeOwned , Serialize } ;
6
7
7
8
use crate :: {
8
9
global_state:: { GlobalState , GlobalStateSnapshot } ,
9
- lsp_utils:: is_cancelled,
10
10
main_loop:: Task ,
11
11
LspError , Result ,
12
12
} ;
@@ -37,49 +37,55 @@ impl<'a> RequestDispatcher<'a> {
37
37
pub ( crate ) fn on_sync_mut < R > (
38
38
& mut self ,
39
39
f : fn ( & mut GlobalState , R :: Params ) -> Result < R :: Result > ,
40
- ) -> Result < & mut Self >
40
+ ) -> & mut Self
41
41
where
42
42
R : lsp_types:: request:: Request ,
43
43
R :: Params : DeserializeOwned + panic:: UnwindSafe + fmt:: Debug ,
44
44
R :: Result : Serialize ,
45
45
{
46
- let ( id , params, panic_context) = match self . parse :: < R > ( ) {
46
+ let ( req , params, panic_context) = match self . parse :: < R > ( ) {
47
47
Some ( it) => it,
48
- None => return Ok ( self ) ,
48
+ None => return self ,
49
+ } ;
50
+ let result = {
51
+ let _pctx = stdx:: panic_context:: enter ( panic_context) ;
52
+ f ( self . global_state , params)
53
+ } ;
54
+ match result_to_response :: < R > ( req. id . clone ( ) , result) {
55
+ Ok ( response) => self . global_state . respond ( response) ,
56
+ Err ( _) => self . global_state . task_pool . handle . send_retry ( req) ,
49
57
} ;
50
- let _pctx = stdx:: panic_context:: enter ( panic_context) ;
51
-
52
- let result = f ( self . global_state , params) ;
53
- let response = result_to_response :: < R > ( id, result) ;
54
58
55
- self . global_state . respond ( response) ;
56
- Ok ( self )
59
+ self
57
60
}
58
61
59
62
/// Dispatches the request onto the current thread.
60
63
pub ( crate ) fn on_sync < R > (
61
64
& mut self ,
62
65
f : fn ( GlobalStateSnapshot , R :: Params ) -> Result < R :: Result > ,
63
- ) -> Result < & mut Self >
66
+ ) -> & mut Self
64
67
where
65
- R : lsp_types:: request:: Request + ' static ,
68
+ R : lsp_types:: request:: Request ,
66
69
R :: Params : DeserializeOwned + panic:: UnwindSafe + fmt:: Debug ,
67
70
R :: Result : Serialize ,
68
71
{
69
- let ( id , params, panic_context) = match self . parse :: < R > ( ) {
72
+ let ( req , params, panic_context) = match self . parse :: < R > ( ) {
70
73
Some ( it) => it,
71
- None => return Ok ( self ) ,
74
+ None => return self ,
72
75
} ;
73
76
let global_state_snapshot = self . global_state . snapshot ( ) ;
74
77
75
78
let result = panic:: catch_unwind ( move || {
76
79
let _pctx = stdx:: panic_context:: enter ( panic_context) ;
77
80
f ( global_state_snapshot, params)
78
81
} ) ;
79
- let response = thread_result_to_response :: < R > ( id, result) ;
80
82
81
- self . global_state . respond ( response) ;
82
- Ok ( self )
83
+ match thread_result_to_response :: < R > ( req. id . clone ( ) , result) {
84
+ Ok ( response) => self . global_state . respond ( response) ,
85
+ Err ( _) => self . global_state . task_pool . handle . send_retry ( req) ,
86
+ } ;
87
+
88
+ self
83
89
}
84
90
85
91
/// Dispatches the request onto thread pool
@@ -92,7 +98,7 @@ impl<'a> RequestDispatcher<'a> {
92
98
R :: Params : DeserializeOwned + panic:: UnwindSafe + Send + fmt:: Debug ,
93
99
R :: Result : Serialize ,
94
100
{
95
- let ( id , params, panic_context) = match self . parse :: < R > ( ) {
101
+ let ( req , params, panic_context) = match self . parse :: < R > ( ) {
96
102
Some ( it) => it,
97
103
None => return self ,
98
104
} ;
@@ -104,8 +110,10 @@ impl<'a> RequestDispatcher<'a> {
104
110
let _pctx = stdx:: panic_context:: enter ( panic_context) ;
105
111
f ( world, params)
106
112
} ) ;
107
- let response = thread_result_to_response :: < R > ( id, result) ;
108
- Task :: Response ( response)
113
+ match thread_result_to_response :: < R > ( req. id . clone ( ) , result) {
114
+ Ok ( response) => Task :: Response ( response) ,
115
+ Err ( _) => Task :: Retry ( req) ,
116
+ }
109
117
}
110
118
} ) ;
111
119
@@ -124,7 +132,7 @@ impl<'a> RequestDispatcher<'a> {
124
132
}
125
133
}
126
134
127
- fn parse < R > ( & mut self ) -> Option < ( lsp_server:: RequestId , R :: Params , String ) >
135
+ fn parse < R > ( & mut self ) -> Option < ( lsp_server:: Request , R :: Params , String ) >
128
136
where
129
137
R : lsp_types:: request:: Request ,
130
138
R :: Params : DeserializeOwned + fmt:: Debug ,
@@ -134,12 +142,12 @@ impl<'a> RequestDispatcher<'a> {
134
142
_ => return None ,
135
143
} ;
136
144
137
- let res = crate :: from_json ( R :: METHOD , req. params ) ;
145
+ let res = crate :: from_json ( R :: METHOD , & req. params ) ;
138
146
match res {
139
147
Ok ( params) => {
140
148
let panic_context =
141
149
format ! ( "\n version: {}\n request: {} {:#?}" , env!( "REV" ) , R :: METHOD , params) ;
142
- Some ( ( req. id , params, panic_context) )
150
+ Some ( ( req, params, panic_context) )
143
151
}
144
152
Err ( err) => {
145
153
let response = lsp_server:: Response :: new_err (
@@ -157,7 +165,7 @@ impl<'a> RequestDispatcher<'a> {
157
165
fn thread_result_to_response < R > (
158
166
id : lsp_server:: RequestId ,
159
167
result : thread:: Result < Result < R :: Result > > ,
160
- ) -> lsp_server:: Response
168
+ ) -> Result < lsp_server:: Response , Cancelled >
161
169
where
162
170
R : lsp_types:: request:: Request ,
163
171
R :: Params : DeserializeOwned ,
@@ -166,53 +174,50 @@ where
166
174
match result {
167
175
Ok ( result) => result_to_response :: < R > ( id, result) ,
168
176
Err ( panic) => {
169
- let mut message = "request handler panicked" . to_string ( ) ;
170
-
171
177
let panic_message = panic
172
178
. downcast_ref :: < String > ( )
173
179
. map ( String :: as_str)
174
180
. or_else ( || panic. downcast_ref :: < & str > ( ) . copied ( ) ) ;
175
181
182
+ let mut message = "request handler panicked" . to_string ( ) ;
176
183
if let Some ( panic_message) = panic_message {
177
184
message. push_str ( ": " ) ;
178
185
message. push_str ( panic_message)
179
186
} ;
180
187
181
- lsp_server:: Response :: new_err ( id, lsp_server:: ErrorCode :: InternalError as i32 , message)
188
+ Ok ( lsp_server:: Response :: new_err (
189
+ id,
190
+ lsp_server:: ErrorCode :: InternalError as i32 ,
191
+ message,
192
+ ) )
182
193
}
183
194
}
184
195
}
185
196
186
197
fn result_to_response < R > (
187
198
id : lsp_server:: RequestId ,
188
199
result : Result < R :: Result > ,
189
- ) -> lsp_server:: Response
200
+ ) -> Result < lsp_server:: Response , Cancelled >
190
201
where
191
202
R : lsp_types:: request:: Request ,
192
203
R :: Params : DeserializeOwned ,
193
204
R :: Result : Serialize ,
194
205
{
195
- match result {
206
+ let res = match result {
196
207
Ok ( resp) => lsp_server:: Response :: new_ok ( id, & resp) ,
197
208
Err ( e) => match e. downcast :: < LspError > ( ) {
198
209
Ok ( lsp_error) => lsp_server:: Response :: new_err ( id, lsp_error. code , lsp_error. message ) ,
199
- Err ( e) => {
200
- if is_cancelled ( & * e) {
201
- lsp_server:: Response :: new_err (
202
- id,
203
- lsp_server:: ErrorCode :: ContentModified as i32 ,
204
- "content modified" . to_string ( ) ,
205
- )
206
- } else {
207
- lsp_server:: Response :: new_err (
208
- id,
209
- lsp_server:: ErrorCode :: InternalError as i32 ,
210
- e. to_string ( ) ,
211
- )
212
- }
213
- }
210
+ Err ( e) => match e. downcast :: < Cancelled > ( ) {
211
+ Ok ( cancelled) => return Err ( * cancelled) ,
212
+ Err ( e) => lsp_server:: Response :: new_err (
213
+ id,
214
+ lsp_server:: ErrorCode :: InternalError as i32 ,
215
+ e. to_string ( ) ,
216
+ ) ,
217
+ } ,
214
218
} ,
215
- }
219
+ } ;
220
+ Ok ( res)
216
221
}
217
222
218
223
pub ( crate ) struct NotificationDispatcher < ' a > {
0 commit comments