11//! See [RequestDispatcher].
22use std:: { fmt, panic, thread} ;
33
4+ use ide:: Cancelled ;
45use lsp_server:: ExtractError ;
56use serde:: { de:: DeserializeOwned , Serialize } ;
67
78use crate :: {
89 global_state:: { GlobalState , GlobalStateSnapshot } ,
9- lsp_utils:: is_cancelled,
1010 main_loop:: Task ,
1111 LspError , Result ,
1212} ;
@@ -37,49 +37,55 @@ impl<'a> RequestDispatcher<'a> {
3737 pub ( crate ) fn on_sync_mut < R > (
3838 & mut self ,
3939 f : fn ( & mut GlobalState , R :: Params ) -> Result < R :: Result > ,
40- ) -> Result < & mut Self >
40+ ) -> & mut Self
4141 where
4242 R : lsp_types:: request:: Request ,
4343 R :: Params : DeserializeOwned + panic:: UnwindSafe + fmt:: Debug ,
4444 R :: Result : Serialize ,
4545 {
46- let ( id , params, panic_context) = match self . parse :: < R > ( ) {
46+ let ( req , params, panic_context) = match self . parse :: < R > ( ) {
4747 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) ,
4957 } ;
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) ;
5458
55- self . global_state . respond ( response) ;
56- Ok ( self )
59+ self
5760 }
5861
5962 /// Dispatches the request onto the current thread.
6063 pub ( crate ) fn on_sync < R > (
6164 & mut self ,
6265 f : fn ( GlobalStateSnapshot , R :: Params ) -> Result < R :: Result > ,
63- ) -> Result < & mut Self >
66+ ) -> & mut Self
6467 where
65- R : lsp_types:: request:: Request + ' static ,
68+ R : lsp_types:: request:: Request ,
6669 R :: Params : DeserializeOwned + panic:: UnwindSafe + fmt:: Debug ,
6770 R :: Result : Serialize ,
6871 {
69- let ( id , params, panic_context) = match self . parse :: < R > ( ) {
72+ let ( req , params, panic_context) = match self . parse :: < R > ( ) {
7073 Some ( it) => it,
71- None => return Ok ( self ) ,
74+ None => return self ,
7275 } ;
7376 let global_state_snapshot = self . global_state . snapshot ( ) ;
7477
7578 let result = panic:: catch_unwind ( move || {
7679 let _pctx = stdx:: panic_context:: enter ( panic_context) ;
7780 f ( global_state_snapshot, params)
7881 } ) ;
79- let response = thread_result_to_response :: < R > ( id, result) ;
8082
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
8389 }
8490
8591 /// Dispatches the request onto thread pool
@@ -92,7 +98,7 @@ impl<'a> RequestDispatcher<'a> {
9298 R :: Params : DeserializeOwned + panic:: UnwindSafe + Send + fmt:: Debug ,
9399 R :: Result : Serialize ,
94100 {
95- let ( id , params, panic_context) = match self . parse :: < R > ( ) {
101+ let ( req , params, panic_context) = match self . parse :: < R > ( ) {
96102 Some ( it) => it,
97103 None => return self ,
98104 } ;
@@ -104,8 +110,10 @@ impl<'a> RequestDispatcher<'a> {
104110 let _pctx = stdx:: panic_context:: enter ( panic_context) ;
105111 f ( world, params)
106112 } ) ;
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+ }
109117 }
110118 } ) ;
111119
@@ -124,7 +132,7 @@ impl<'a> RequestDispatcher<'a> {
124132 }
125133 }
126134
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 ) >
128136 where
129137 R : lsp_types:: request:: Request ,
130138 R :: Params : DeserializeOwned + fmt:: Debug ,
@@ -134,12 +142,12 @@ impl<'a> RequestDispatcher<'a> {
134142 _ => return None ,
135143 } ;
136144
137- let res = crate :: from_json ( R :: METHOD , req. params ) ;
145+ let res = crate :: from_json ( R :: METHOD , & req. params ) ;
138146 match res {
139147 Ok ( params) => {
140148 let panic_context =
141149 format ! ( "\n version: {}\n request: {} {:#?}" , env!( "REV" ) , R :: METHOD , params) ;
142- Some ( ( req. id , params, panic_context) )
150+ Some ( ( req, params, panic_context) )
143151 }
144152 Err ( err) => {
145153 let response = lsp_server:: Response :: new_err (
@@ -157,7 +165,7 @@ impl<'a> RequestDispatcher<'a> {
157165fn thread_result_to_response < R > (
158166 id : lsp_server:: RequestId ,
159167 result : thread:: Result < Result < R :: Result > > ,
160- ) -> lsp_server:: Response
168+ ) -> Result < lsp_server:: Response , Cancelled >
161169where
162170 R : lsp_types:: request:: Request ,
163171 R :: Params : DeserializeOwned ,
@@ -166,53 +174,50 @@ where
166174 match result {
167175 Ok ( result) => result_to_response :: < R > ( id, result) ,
168176 Err ( panic) => {
169- let mut message = "request handler panicked" . to_string ( ) ;
170-
171177 let panic_message = panic
172178 . downcast_ref :: < String > ( )
173179 . map ( String :: as_str)
174180 . or_else ( || panic. downcast_ref :: < & str > ( ) . copied ( ) ) ;
175181
182+ let mut message = "request handler panicked" . to_string ( ) ;
176183 if let Some ( panic_message) = panic_message {
177184 message. push_str ( ": " ) ;
178185 message. push_str ( panic_message)
179186 } ;
180187
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+ ) )
182193 }
183194 }
184195}
185196
186197fn result_to_response < R > (
187198 id : lsp_server:: RequestId ,
188199 result : Result < R :: Result > ,
189- ) -> lsp_server:: Response
200+ ) -> Result < lsp_server:: Response , Cancelled >
190201where
191202 R : lsp_types:: request:: Request ,
192203 R :: Params : DeserializeOwned ,
193204 R :: Result : Serialize ,
194205{
195- match result {
206+ let res = match result {
196207 Ok ( resp) => lsp_server:: Response :: new_ok ( id, & resp) ,
197208 Err ( e) => match e. downcast :: < LspError > ( ) {
198209 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+ } ,
214218 } ,
215- }
219+ } ;
220+ Ok ( res)
216221}
217222
218223pub ( crate ) struct NotificationDispatcher < ' a > {
0 commit comments