1+ use std:: borrow:: Cow ;
2+
13use thiserror:: Error ;
24
35use super :: * ;
@@ -19,7 +21,7 @@ use crate::model::{
1921///
2022/// if you want to handle the error, you can use `serve_client_with_ct` or `serve_client` with `Result<RunningService<RoleClient, S>, ClientError>`
2123#[ derive( Error , Debug ) ]
22- pub enum ClientError {
24+ pub enum ClientInitializeError < E > {
2325 #[ error( "expect initialized response, but received: {0:?}" ) ]
2426 ExpectedInitResponse ( Option < ServerJsonRpcMessage > ) ,
2527
@@ -32,38 +34,40 @@ pub enum ClientError {
3234 #[ error( "connection closed: {0}" ) ]
3335 ConnectionClosed ( String ) ,
3436
35- #[ error( "IO error: {0}" ) ]
36- Io ( #[ from] std:: io:: Error ) ,
37+ #[ error( "Send message error {error}, when {context}" ) ]
38+ TransportError {
39+ error : E ,
40+ context : Cow < ' static , str > ,
41+ } ,
3742}
3843
3944/// Helper function to get the next message from the stream
40- async fn expect_next_message < T > (
45+ async fn expect_next_message < T , E > (
4146 transport : & mut T ,
4247 context : & str ,
43- ) -> Result < ServerJsonRpcMessage , ClientError >
48+ ) -> Result < ServerJsonRpcMessage , ClientInitializeError < E > >
4449where
4550 T : Transport < RoleClient > ,
4651{
4752 transport
4853 . receive ( )
4954 . await
50- . ok_or_else ( || ClientError :: ConnectionClosed ( context. to_string ( ) ) )
51- . map_err ( |e| ClientError :: Io ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e) ) )
55+ . ok_or_else ( || ClientInitializeError :: ConnectionClosed ( context. to_string ( ) ) )
5256}
5357
5458/// Helper function to expect a response from the stream
55- async fn expect_response < T > (
59+ async fn expect_response < T , E > (
5660 transport : & mut T ,
5761 context : & str ,
58- ) -> Result < ( ServerResult , RequestId ) , ClientError >
62+ ) -> Result < ( ServerResult , RequestId ) , ClientInitializeError < E > >
5963where
6064 T : Transport < RoleClient > ,
6165{
6266 let msg = expect_next_message ( transport, context) . await ?;
6367
6468 match msg {
6569 ServerJsonRpcMessage :: Response ( JsonRpcResponse { id, result, .. } ) => Ok ( ( result, id) ) ,
66- _ => Err ( ClientError :: ExpectedInitResponse ( Some ( msg) ) ) ,
70+ _ => Err ( ClientInitializeError :: ExpectedInitResponse ( Some ( msg) ) ) ,
6771 }
6872}
6973
@@ -79,7 +83,7 @@ impl ServiceRole for RoleClient {
7983 type PeerNot = ServerNotification ;
8084 type Info = ClientInfo ;
8185 type PeerInfo = ServerInfo ;
82-
86+ type InitializeError < E > = ClientInitializeError < E > ;
8387 const IS_CLIENT : bool = true ;
8488}
8589
@@ -90,7 +94,7 @@ impl<S: Service<RoleClient>> ServiceExt<RoleClient> for S {
9094 self ,
9195 transport : T ,
9296 ct : CancellationToken ,
93- ) -> impl Future < Output = Result < RunningService < RoleClient , Self > , E > > + Send
97+ ) -> impl Future < Output = Result < RunningService < RoleClient , Self > , ClientInitializeError < E > > > + Send
9498 where
9599 T : IntoTransport < RoleClient , E , A > ,
96100 E : std:: error:: Error + From < std:: io:: Error > + Send + Sync + ' static ,
@@ -103,7 +107,7 @@ impl<S: Service<RoleClient>> ServiceExt<RoleClient> for S {
103107pub async fn serve_client < S , T , E , A > (
104108 service : S ,
105109 transport : T ,
106- ) -> Result < RunningService < RoleClient , S > , E >
110+ ) -> Result < RunningService < RoleClient , S > , ClientInitializeError < E > >
107111where
108112 S : Service < RoleClient > ,
109113 T : IntoTransport < RoleClient , E , A > ,
@@ -116,7 +120,7 @@ pub async fn serve_client_with_ct<S, T, E, A>(
116120 service : S ,
117121 transport : T ,
118122 ct : CancellationToken ,
119- ) -> Result < RunningService < RoleClient , S > , E >
123+ ) -> Result < RunningService < RoleClient , S > , ClientInitializeError < E > >
120124where
121125 S : Service < RoleClient > ,
122126 T : IntoTransport < RoleClient , E , A > ,
@@ -125,14 +129,6 @@ where
125129 let mut transport = transport. into_transport ( ) ;
126130 let id_provider = <Arc < AtomicU32RequestIdProvider > >:: default ( ) ;
127131
128- // Convert ClientError to std::io::Error, then to E
129- let handle_client_error = |e : ClientError | -> E {
130- match e {
131- ClientError :: Io ( io_err) => io_err. into ( ) ,
132- other => std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , format ! ( "{}" , other) ) . into ( ) ,
133- }
134- } ;
135-
136132 // service
137133 let id = id_provider. next_request_id ( ) ;
138134 let init_request = InitializeRequest {
@@ -145,23 +141,23 @@ where
145141 ClientRequest :: InitializeRequest ( init_request) ,
146142 id. clone ( ) ,
147143 ) )
148- . await ?;
149-
150- let ( response, response_id) = expect_response ( & mut transport, "initialize response" )
151144 . await
152- . map_err ( handle_client_error) ?;
145+ . map_err ( |error| ClientInitializeError :: TransportError {
146+ error,
147+ context : "send initialize request" . into ( ) ,
148+ } ) ?;
149+
150+ let ( response, response_id) = expect_response ( & mut transport, "initialize response" ) . await ?;
153151
154152 if id != response_id {
155- return Err ( handle_client_error ( ClientError :: ConflictInitResponseId (
153+ return Err ( ClientInitializeError :: ConflictInitResponseId (
156154 id,
157155 response_id,
158- ) ) ) ;
156+ ) ) ;
159157 }
160158
161159 let ServerResult :: InitializeResult ( initialize_result) = response else {
162- return Err ( handle_client_error ( ClientError :: ExpectedInitResult ( Some (
163- response,
164- ) ) ) ) ;
160+ return Err ( ClientInitializeError :: ExpectedInitResult ( Some ( response) ) ) ;
165161 } ;
166162
167163 // send notification
@@ -171,9 +167,15 @@ where
171167 extensions : Default :: default ( ) ,
172168 } ) ,
173169 ) ;
174- transport. send ( notification) . await ?;
170+ transport
171+ . send ( notification)
172+ . await
173+ . map_err ( |error| ClientInitializeError :: TransportError {
174+ error,
175+ context : "send initialized notification" . into ( ) ,
176+ } ) ?;
175177 let ( peer, peer_rx) = Peer :: new ( id_provider, initialize_result) ;
176- serve_inner ( service, transport, peer, peer_rx, ct) . await
178+ Ok ( serve_inner ( service, transport, peer, peer_rx, ct) . await )
177179}
178180
179181macro_rules! method {
0 commit comments