Skip to content

Commit 2ed6d60

Browse files
authored
Merge pull request #131 from kinode-dao/develop
update error types
2 parents d791baa + 2ba06dd commit 2ed6d60

File tree

5 files changed

+94
-183
lines changed

5 files changed

+94
-183
lines changed

src/http/client.rs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ pub enum HttpClientAction {
3030
},
3131
}
3232

33-
/// HTTP Request type that can be shared over Wasm boundary to apps.
34-
/// This is the one you send to the `http-client:distro:sys` service.
33+
/// HTTP Request type contained in [`HttpClientAction::Http`].
3534
///
3635
/// BODY is stored in the lazy_load_blob, as bytes
3736
///
38-
/// TIMEOUT is stored in the message expect_response value
37+
/// TIMEOUT is stored in the message's `expects_response` value
3938
#[derive(Clone, Debug, Serialize, Deserialize)]
4039
pub struct OutgoingHttpRequest {
4140
/// must parse to [`http::Method`]
@@ -63,32 +62,38 @@ pub enum HttpClientRequest {
6362

6463
/// [`crate::Response`] type received from the `http-client:distro:sys` service after
6564
/// sending a successful [`HttpClientAction`] to it.
66-
#[derive(Debug, Serialize, Deserialize)]
65+
#[derive(Clone, Debug, Serialize, Deserialize)]
6766
pub enum HttpClientResponse {
6867
Http(HttpResponse),
6968
WebSocketAck,
7069
}
7170

72-
#[derive(Error, Debug, Serialize, Deserialize)]
71+
#[derive(Clone, Debug, Error, Serialize, Deserialize)]
7372
pub enum HttpClientError {
7473
// HTTP errors
75-
#[error("http-client: request is not valid HttpClientRequest: {req}.")]
76-
BadRequest { req: String },
77-
#[error("http-client: http method not supported: {method}.")]
74+
#[error("request could not be deserialized to valid HttpClientRequest")]
75+
MalformedRequest,
76+
#[error("http method not supported: {method}")]
7877
BadMethod { method: String },
79-
#[error("http-client: url could not be parsed: {url}.")]
78+
#[error("url could not be parsed: {url}")]
8079
BadUrl { url: String },
81-
#[error("http-client: http version not supported: {version}.")]
80+
#[error("http version not supported: {version}")]
8281
BadVersion { version: String },
83-
#[error("http-client: failed to execute request {error}.")]
84-
RequestFailed { error: String },
82+
#[error("client failed to build request: {0}")]
83+
BuildRequestFailed(String),
84+
#[error("client failed to execute request: {0}")]
85+
ExecuteRequestFailed(String),
8586

8687
// WebSocket errors
87-
#[error("websocket_client: failed to open connection {url}.")]
88+
#[error("could not open connection to {url}")]
8889
WsOpenFailed { url: String },
89-
#[error("websocket_client: failed to send message {req}.")]
90-
WsPushFailed { req: String },
91-
#[error("websocket_client: failed to close connection {channel_id}.")]
90+
#[error("sent WebSocket push to unknown channel {channel_id}")]
91+
WsPushUnknownChannel { channel_id: u32 },
92+
#[error("WebSocket push failed because message had no blob attached")]
93+
WsPushNoBlob,
94+
#[error("WebSocket push failed because message type was Text, but blob was not a valid UTF-8 string")]
95+
WsPushBadText,
96+
#[error("failed to close connection {channel_id} because it was not open")]
9297
WsCloseFailed { channel_id: u32 },
9398
}
9499

@@ -141,48 +146,42 @@ pub fn send_request_await_response(
141146
url: url.to_string(),
142147
headers: headers.unwrap_or_default(),
143148
}))
144-
.map_err(|e| HttpClientError::BadRequest {
145-
req: format!("{e:?}"),
146-
})?,
149+
.map_err(|_| HttpClientError::MalformedRequest)?,
147150
)
148151
.blob_bytes(body)
149152
.send_and_await_response(timeout)
150153
.unwrap();
151154
let Ok(Message::Response { body, .. }) = res else {
152-
return Err(HttpClientError::RequestFailed {
153-
error: "http-client timed out".to_string(),
154-
});
155+
return Err(HttpClientError::ExecuteRequestFailed(
156+
"http-client timed out".to_string(),
157+
));
155158
};
156159
let resp = match serde_json::from_slice::<
157160
std::result::Result<HttpClientResponse, HttpClientError>,
158161
>(&body)
159162
{
160163
Ok(Ok(HttpClientResponse::Http(resp))) => resp,
161164
Ok(Ok(HttpClientResponse::WebSocketAck)) => {
162-
return Err(HttpClientError::RequestFailed {
163-
error: "http-client gave unexpected response".to_string(),
164-
})
165+
return Err(HttpClientError::ExecuteRequestFailed(
166+
"http-client gave unexpected response".to_string(),
167+
))
165168
}
166169
Ok(Err(e)) => return Err(e),
167170
Err(e) => {
168-
return Err(HttpClientError::RequestFailed {
169-
error: format!("http-client gave invalid response: {e:?}"),
170-
})
171+
return Err(HttpClientError::ExecuteRequestFailed(format!(
172+
"http-client gave invalid response: {e:?}"
173+
)))
171174
}
172175
};
173176
let mut http_response = http::Response::builder()
174177
.status(http::StatusCode::from_u16(resp.status).unwrap_or_default());
175178
let headers = http_response.headers_mut().unwrap();
176179
for (key, value) in &resp.headers {
177180
let Ok(key) = http::header::HeaderName::from_str(key) else {
178-
return Err(HttpClientError::RequestFailed {
179-
error: format!("http-client gave invalid header key: {key}"),
180-
});
181+
continue;
181182
};
182183
let Ok(value) = http::header::HeaderValue::from_str(value) else {
183-
return Err(HttpClientError::RequestFailed {
184-
error: format!("http-client gave invalid header value: {value}"),
185-
});
184+
continue;
186185
};
187186
headers.insert(key, value);
188187
}

src/http/server.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -268,14 +268,16 @@ impl HttpResponse {
268268
/// Part of the [`crate::Response`] type issued by http-server
269269
#[derive(Clone, Debug, Error, Serialize, Deserialize)]
270270
pub enum HttpServerError {
271-
#[error("request could not be parsed to HttpServerAction: {req}.")]
272-
BadRequest { req: String },
273-
#[error("action expected lazy_load_blob")]
271+
#[error("request could not be deserialized to valid HttpServerRequest")]
272+
MalformedRequest,
273+
#[error("action expected blob")]
274274
NoBlob,
275-
#[error("path binding error: {error}")]
276-
PathBindError { error: String },
277-
#[error("WebSocket error: {error}")]
278-
WebSocketPushError { error: String },
275+
#[error("path binding error: invalid source process")]
276+
InvalidSourceProcess,
277+
#[error("WebSocket error: ping/pong message too long")]
278+
WsPingPongTooLong,
279+
#[error("WebSocket error: channel not found")]
280+
WsChannelNotFound,
279281
/// Not actually issued by `http-server:distro:sys`, just this library
280282
#[error("timeout")]
281283
Timeout,
@@ -683,9 +685,7 @@ impl HttpServer {
683685
let entry = self
684686
.http_paths
685687
.get_mut(path)
686-
.ok_or(HttpServerError::PathBindError {
687-
error: "path not found".to_string(),
688-
})?;
688+
.ok_or(HttpServerError::MalformedRequest)?;
689689
let res = KiRequest::to(("our", "http-server", "distro", "sys"))
690690
.body(
691691
serde_json::to_vec(&HttpServerAction::Bind {
@@ -722,9 +722,7 @@ impl HttpServer {
722722
let entry = self
723723
.ws_paths
724724
.get_mut(path)
725-
.ok_or(HttpServerError::PathBindError {
726-
error: "path not found".to_string(),
727-
})?;
725+
.ok_or(HttpServerError::MalformedRequest)?;
728726
let res = KiRequest::to(("our", "http-server", "distro", "sys"))
729727
.body(if entry.secure_subdomain {
730728
serde_json::to_vec(&HttpServerAction::WebSocketSecureBind {
@@ -826,7 +824,7 @@ impl HttpServer {
826824
),
827825
action: VfsAction::Read,
828826
})
829-
.map_err(|e| HttpServerError::BadRequest { req: e.to_string() })?,
827+
.map_err(|_| HttpServerError::MalformedRequest)?,
830828
)
831829
.send_and_await_response(self.timeout)
832830
.unwrap();
@@ -861,7 +859,7 @@ impl HttpServer {
861859
path: file_path.to_string(),
862860
action: VfsAction::Read,
863861
})
864-
.map_err(|e| HttpServerError::BadRequest { req: e.to_string() })?,
862+
.map_err(|_| HttpServerError::MalformedRequest)?,
865863
)
866864
.send_and_await_response(self.timeout)
867865
.unwrap();
@@ -911,9 +909,7 @@ impl HttpServer {
911909
.send_and_await_response(self.timeout)
912910
.unwrap()
913911
else {
914-
return Err(HttpServerError::PathBindError {
915-
error: format!("no ui directory to serve: {initial_path}"),
916-
});
912+
return Err(HttpServerError::MalformedRequest);
917913
};
918914

919915
let directory_body = serde_json::from_slice::<VfsResponse>(directory_response.body())
@@ -976,7 +972,7 @@ impl HttpServer {
976972

977973
pub fn parse_request(&self, body: &[u8]) -> Result<HttpServerRequest, HttpServerError> {
978974
let request = serde_json::from_slice::<HttpServerRequest>(body)
979-
.map_err(|e| HttpServerError::BadRequest { req: e.to_string() })?;
975+
.map_err(|_| HttpServerError::MalformedRequest)?;
980976
Ok(request)
981977
}
982978

src/vfs/directory.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ impl Directory {
1515
let message = vfs_request(&self.path, VfsAction::ReadDir)
1616
.send_and_await_response(self.timeout)
1717
.unwrap()
18-
.map_err(|e| VfsError::IOError {
19-
error: e.to_string(),
20-
path: self.path.clone(),
21-
})?;
18+
.map_err(|e| VfsError::SendError(e.kind))?;
2219

2320
match parse_response(message.body())? {
2421
VfsResponse::ReadDir(entries) => Ok(entries),
@@ -39,17 +36,13 @@ pub fn open_dir(path: &str, create: bool, timeout: Option<u64>) -> Result<Direct
3936
let message = vfs_request(path, VfsAction::Metadata)
4037
.send_and_await_response(timeout)
4138
.unwrap()
42-
.map_err(|e| VfsError::IOError {
43-
error: e.to_string(),
44-
path: path.to_string(),
45-
})?;
39+
.map_err(|e| VfsError::SendError(e.kind))?;
4640
match parse_response(message.body())? {
4741
VfsResponse::Metadata(m) => {
4842
if m.file_type != FileType::Directory {
49-
return Err(VfsError::IOError {
50-
error: "Entry at path not a directory".to_string(),
51-
path: path.to_string(),
52-
});
43+
return Err(VfsError::IOError(
44+
"entry at path is not a directory".to_string(),
45+
));
5346
}
5447
}
5548
VfsResponse::Err(e) => return Err(e),
@@ -70,10 +63,7 @@ pub fn open_dir(path: &str, create: bool, timeout: Option<u64>) -> Result<Direct
7063
let message = vfs_request(path, VfsAction::CreateDirAll)
7164
.send_and_await_response(timeout)
7265
.unwrap()
73-
.map_err(|e| VfsError::IOError {
74-
error: e.to_string(),
75-
path: path.to_string(),
76-
})?;
66+
.map_err(|e| VfsError::SendError(e.kind))?;
7767

7868
match parse_response(message.body())? {
7969
VfsResponse::Ok => Ok(Directory {
@@ -95,10 +85,7 @@ pub fn remove_dir(path: &str, timeout: Option<u64>) -> Result<(), VfsError> {
9585
let message = vfs_request(path, VfsAction::RemoveDir)
9686
.send_and_await_response(timeout)
9787
.unwrap()
98-
.map_err(|e| VfsError::IOError {
99-
error: e.to_string(),
100-
path: path.to_string(),
101-
})?;
88+
.map_err(|e| VfsError::SendError(e.kind))?;
10289

10390
match parse_response(message.body())? {
10491
VfsResponse::Ok => Ok(()),

0 commit comments

Comments
 (0)