1
+ use std:: borrow:: Cow ;
2
+
1
3
use thiserror:: Error ;
2
4
3
5
use super :: * ;
@@ -19,7 +21,7 @@ use crate::model::{
19
21
///
20
22
/// if you want to handle the error, you can use `serve_client_with_ct` or `serve_client` with `Result<RunningService<RoleClient, S>, ClientError>`
21
23
#[ derive( Error , Debug ) ]
22
- pub enum ClientError {
24
+ pub enum ClientInitializeError < E > {
23
25
#[ error( "expect initialized response, but received: {0:?}" ) ]
24
26
ExpectedInitResponse ( Option < ServerJsonRpcMessage > ) ,
25
27
@@ -32,38 +34,40 @@ pub enum ClientError {
32
34
#[ error( "connection closed: {0}" ) ]
33
35
ConnectionClosed ( String ) ,
34
36
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
+ } ,
37
42
}
38
43
39
44
/// 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 > (
41
46
transport : & mut T ,
42
47
context : & str ,
43
- ) -> Result < ServerJsonRpcMessage , ClientError >
48
+ ) -> Result < ServerJsonRpcMessage , ClientInitializeError < E > >
44
49
where
45
50
T : Transport < RoleClient > ,
46
51
{
47
52
transport
48
53
. receive ( )
49
54
. 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 ( ) ) )
52
56
}
53
57
54
58
/// Helper function to expect a response from the stream
55
- async fn expect_response < T > (
59
+ async fn expect_response < T , E > (
56
60
transport : & mut T ,
57
61
context : & str ,
58
- ) -> Result < ( ServerResult , RequestId ) , ClientError >
62
+ ) -> Result < ( ServerResult , RequestId ) , ClientInitializeError < E > >
59
63
where
60
64
T : Transport < RoleClient > ,
61
65
{
62
66
let msg = expect_next_message ( transport, context) . await ?;
63
67
64
68
match msg {
65
69
ServerJsonRpcMessage :: Response ( JsonRpcResponse { id, result, .. } ) => Ok ( ( result, id) ) ,
66
- _ => Err ( ClientError :: ExpectedInitResponse ( Some ( msg) ) ) ,
70
+ _ => Err ( ClientInitializeError :: ExpectedInitResponse ( Some ( msg) ) ) ,
67
71
}
68
72
}
69
73
@@ -79,7 +83,7 @@ impl ServiceRole for RoleClient {
79
83
type PeerNot = ServerNotification ;
80
84
type Info = ClientInfo ;
81
85
type PeerInfo = ServerInfo ;
82
-
86
+ type InitializeError < E > = ClientInitializeError < E > ;
83
87
const IS_CLIENT : bool = true ;
84
88
}
85
89
@@ -90,7 +94,7 @@ impl<S: Service<RoleClient>> ServiceExt<RoleClient> for S {
90
94
self ,
91
95
transport : T ,
92
96
ct : CancellationToken ,
93
- ) -> impl Future < Output = Result < RunningService < RoleClient , Self > , E > > + Send
97
+ ) -> impl Future < Output = Result < RunningService < RoleClient , Self > , ClientInitializeError < E > > > + Send
94
98
where
95
99
T : IntoTransport < RoleClient , E , A > ,
96
100
E : std:: error:: Error + From < std:: io:: Error > + Send + Sync + ' static ,
@@ -103,7 +107,7 @@ impl<S: Service<RoleClient>> ServiceExt<RoleClient> for S {
103
107
pub async fn serve_client < S , T , E , A > (
104
108
service : S ,
105
109
transport : T ,
106
- ) -> Result < RunningService < RoleClient , S > , E >
110
+ ) -> Result < RunningService < RoleClient , S > , ClientInitializeError < E > >
107
111
where
108
112
S : Service < RoleClient > ,
109
113
T : IntoTransport < RoleClient , E , A > ,
@@ -116,7 +120,7 @@ pub async fn serve_client_with_ct<S, T, E, A>(
116
120
service : S ,
117
121
transport : T ,
118
122
ct : CancellationToken ,
119
- ) -> Result < RunningService < RoleClient , S > , E >
123
+ ) -> Result < RunningService < RoleClient , S > , ClientInitializeError < E > >
120
124
where
121
125
S : Service < RoleClient > ,
122
126
T : IntoTransport < RoleClient , E , A > ,
@@ -125,14 +129,6 @@ where
125
129
let mut transport = transport. into_transport ( ) ;
126
130
let id_provider = <Arc < AtomicU32RequestIdProvider > >:: default ( ) ;
127
131
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
-
136
132
// service
137
133
let id = id_provider. next_request_id ( ) ;
138
134
let init_request = InitializeRequest {
@@ -145,23 +141,23 @@ where
145
141
ClientRequest :: InitializeRequest ( init_request) ,
146
142
id. clone ( ) ,
147
143
) )
148
- . await ?;
149
-
150
- let ( response, response_id) = expect_response ( & mut transport, "initialize response" )
151
144
. 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 ?;
153
151
154
152
if id != response_id {
155
- return Err ( handle_client_error ( ClientError :: ConflictInitResponseId (
153
+ return Err ( ClientInitializeError :: ConflictInitResponseId (
156
154
id,
157
155
response_id,
158
- ) ) ) ;
156
+ ) ) ;
159
157
}
160
158
161
159
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) ) ) ;
165
161
} ;
166
162
167
163
// send notification
@@ -171,9 +167,15 @@ where
171
167
extensions : Default :: default ( ) ,
172
168
} ) ,
173
169
) ;
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
+ } ) ?;
175
177
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 )
177
179
}
178
180
179
181
macro_rules! method {
0 commit comments