fix http-client error types

This commit is contained in:
dr-frmr 2024-12-23 01:43:54 -05:00
parent e824e61ec3
commit d23d454ad1
No known key found for this signature in database
3 changed files with 37 additions and 45 deletions

View File

@ -64,9 +64,7 @@ pub async fn http_client(
id,
rsvp.unwrap_or(source),
expects_response,
HttpClientError::BadRequest {
req: String::from_utf8(body).unwrap_or_default(),
},
HttpClientError::MalformedRequest,
send_to_loop.clone(),
)
.await;
@ -197,8 +195,8 @@ async fn connect_websocket(
};
let Ok(mut req) = url.clone().into_client_request() else {
return Err(HttpClientError::BadRequest {
req: "failed to parse url into client request".into(),
return Err(HttpClientError::WsOpenFailed {
url: url.to_string(),
});
};
@ -443,18 +441,16 @@ async fn handle_http_request(
}
// Add the headers
let Ok(request) = request_builder
let build = request_builder
.headers(deserialize_headers(req.headers))
.build()
else {
.build();
if let Err(e) = build {
http_error_message(
our,
id,
target,
expects_response,
HttpClientError::RequestFailed {
error: "failed to build request".into(),
},
HttpClientError::BuildRequestFailed(e.to_string()),
send_to_loop,
)
.await;
@ -462,7 +458,7 @@ async fn handle_http_request(
};
// Send the HTTP request
match client.execute(request).await {
match client.execute(build.unwrap()).await {
Ok(response) => {
// Handle the response and forward to the target process
let Ok(body) = serde_json::to_vec::<Result<HttpClientResponse, HttpClientError>>(&Ok(
@ -512,9 +508,7 @@ async fn handle_http_request(
id,
target,
expects_response,
HttpClientError::RequestFailed {
error: e.to_string(),
},
HttpClientError::ExecuteRequestFailed(e.to_string()),
send_to_loop,
)
.await;
@ -612,32 +606,24 @@ async fn send_ws_push(
ws_streams: WebSocketStreams,
) -> Result<HttpClientResponse, HttpClientError> {
let Some(mut ws_stream) = ws_streams.get_mut(&(target.process.clone(), channel_id)) else {
return Err(HttpClientError::WsPushFailed {
req: format!("channel_id {} not found", channel_id),
});
return Err(HttpClientError::WsPushUnknownChannel { channel_id });
};
let _ = match message_type {
WsMessageType::Text => {
let Some(blob) = blob else {
return Err(HttpClientError::WsPushFailed {
req: "no blob".into(),
});
return Err(HttpClientError::WsPushNoBlob);
};
let Ok(text) = String::from_utf8(blob.bytes) else {
return Err(HttpClientError::WsPushFailed {
req: "failed to convert blob to string".into(),
});
return Err(HttpClientError::WsPushBadText);
};
ws_stream.send(TungsteniteMessage::Text(text)).await
}
WsMessageType::Binary => {
let Some(blob) = blob else {
return Err(HttpClientError::WsPushFailed {
req: "no blob".into(),
});
return Err(HttpClientError::WsPushNoBlob);
};
ws_stream.send(TungsteniteMessage::Binary(blob.bytes)).await

View File

@ -23,12 +23,11 @@ pub enum HttpClientAction {
},
}
/// HTTP Request type that can be shared over Wasm boundary to apps.
/// This is the one you send to the `http-client:distro:sys` service.
/// HTTP Request type contained in [`HttpClientAction::Http`].
///
/// BODY is stored in the lazy_load_blob, as bytes
///
/// TIMEOUT is stored in the message expect_response value
/// TIMEOUT is stored in the message's `expects_response` value
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OutgoingHttpRequest {
/// must parse to [`http::Method`]
@ -56,31 +55,37 @@ pub enum HttpClientRequest {
/// Response type received from the `http-client:distro:sys` service after
/// sending a successful [`HttpClientAction`] to it.
#[derive(Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum HttpClientResponse {
Http(HttpResponse),
WebSocketAck,
}
#[derive(Error, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Error, Serialize, Deserialize)]
pub enum HttpClientError {
// HTTP errors
#[error("http-client: request is not valid HttpClientRequest: {req}.")]
BadRequest { req: String },
#[error("http-client: http method not supported: {method}.")]
#[error("request could not be deserialized to valid HttpClientRequest")]
MalformedRequest,
#[error("http method not supported: {method}")]
BadMethod { method: String },
#[error("http-client: url could not be parsed: {url}.")]
#[error("url could not be parsed: {url}")]
BadUrl { url: String },
#[error("http-client: http version not supported: {version}.")]
#[error("http version not supported: {version}")]
BadVersion { version: String },
#[error("http-client: failed to execute request {error}.")]
RequestFailed { error: String },
#[error("client failed to build request: {0}")]
BuildRequestFailed(String),
#[error("client failed to execute request: {0}")]
ExecuteRequestFailed(String),
// WebSocket errors
#[error("http-client: failed to open connection {url}.")]
#[error("could not open connection to {url}")]
WsOpenFailed { url: String },
#[error("http-client: failed to send message {req}.")]
WsPushFailed { req: String },
#[error("http-client: failed to close connection {channel_id}.")]
#[error("sent WebSocket push to unknown channel {channel_id}")]
WsPushUnknownChannel { channel_id: u32 },
#[error("WebSocket push failed because message had no blob attached")]
WsPushNoBlob,
#[error("WebSocket push failed because message type was Text, but blob was not a valid UTF-8 string")]
WsPushBadText,
#[error("failed to close connection {channel_id} because it was not open")]
WsCloseFailed { channel_id: u32 },
}

View File

@ -48,11 +48,12 @@ pub struct IncomingHttpRequest {
/// HTTP Response type that can be shared over Wasm boundary to apps.
/// Respond to [`IncomingHttpRequest`] with this type.
#[derive(Debug, Serialize, Deserialize)]
///
/// BODY is stored in the lazy_load_blob, as bytes
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct HttpResponse {
pub status: u16,
pub headers: HashMap<String, String>,
// BODY is stored in the lazy_load_blob, as bytes
}
#[derive(Debug, Serialize, Deserialize)]