11//! A visitor for downcasting arbitrary request (JSON) into a specific type.
2- use std:: { fmt, panic} ;
2+ use std:: { fmt, panic, thread } ;
33
44use serde:: { de:: DeserializeOwned , Serialize } ;
55
@@ -32,7 +32,7 @@ impl<'a> RequestDispatcher<'a> {
3232 } ;
3333 let global_state = panic:: AssertUnwindSafe ( & mut * self . global_state ) ;
3434
35- let response = panic:: catch_unwind ( move || {
35+ let result = panic:: catch_unwind ( move || {
3636 let _ = & global_state;
3737 let panic:: AssertUnwindSafe ( global_state) = global_state;
3838 let _pctx = stdx:: panic_context:: enter ( format ! (
@@ -41,10 +41,10 @@ impl<'a> RequestDispatcher<'a> {
4141 R :: METHOD ,
4242 params
4343 ) ) ;
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+
4848 self . global_state . respond ( response) ;
4949 Ok ( self )
5050 }
@@ -56,7 +56,7 @@ impl<'a> RequestDispatcher<'a> {
5656 ) -> & mut Self
5757 where
5858 R : lsp_types:: request:: Request + ' static ,
59- R :: Params : DeserializeOwned + Send + fmt:: Debug + ' static ,
59+ R :: Params : DeserializeOwned + panic :: UnwindSafe + Send + fmt:: Debug + ' static ,
6060 R :: Result : Serialize + ' static ,
6161 {
6262 let ( id, params) = match self . parse :: < R > ( ) {
@@ -66,16 +66,18 @@ impl<'a> RequestDispatcher<'a> {
6666
6767 self . global_state . task_pool . handle . spawn ( {
6868 let world = self . global_state . snapshot ( ) ;
69-
7069 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)
7981 }
8082 } ) ;
8183
@@ -122,16 +124,16 @@ impl<'a> RequestDispatcher<'a> {
122124
123125fn result_to_response < R > (
124126 id : lsp_server:: RequestId ,
125- result : Result < R :: Result > ,
127+ result : thread :: Result < Result < R :: Result > > ,
126128) -> lsp_server:: Response
127129where
128130 R : lsp_types:: request:: Request + ' static ,
129131 R :: Params : DeserializeOwned + ' static ,
130132 R :: Result : Serialize + ' static ,
131133{
132134 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 > ( ) {
135137 Ok ( lsp_error) => lsp_server:: Response :: new_err ( id, lsp_error. code , lsp_error. message ) ,
136138 Err ( e) => {
137139 if is_cancelled ( & * e) {
@@ -149,6 +151,21 @@ where
149151 }
150152 }
151153 } ,
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+ }
152169 }
153170}
154171
0 commit comments