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