-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient_request_error.rs
More file actions
73 lines (65 loc) · 2.38 KB
/
Copy pathclient_request_error.rs
File metadata and controls
73 lines (65 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use actix_http::{encoding::Decoder, Payload, PayloadStream};
use awc::error::{JsonPayloadError, SendRequestError};
use awc::http::StatusCode;
use awc::ClientResponse;
use serde::de::DeserializeOwned;
use std::future::Future;
use crate::errors::ErrorResponse;
/// Enum with all of the things that can go wrong when making a client request
#[derive(Debug)]
pub enum ClientRequestError {
SendError(SendRequestError),
ResponseError(ErrorResponse),
JSONError(JsonPayloadError),
UnknownError(StatusCode),
}
impl ClientRequestError {
/// Handle the response from a client and parse the JSON body
///
/// Returns an error if any of these steps fail
pub async fn handle<T: DeserializeOwned>(
input: impl Future<Output = Result<ClientResponse<Decoder<Payload<PayloadStream>>>, SendRequestError>>,
) -> Result<T, Self> {
match input.await {
Err(e) => Err(Self::SendError(e)),
Ok(mut response) => {
// Try to deserialize the data if the request is ok
let status = response.status();
if response.status() == StatusCode::OK {
return response.json::<T>().await.map_err(|e| Self::JSONError(e));
}
// Otherwise, possibly parse an error response
// If the server didn't return an error response, then just return the status code
let error_response = response
.json::<ErrorResponse>()
.await
.map_err(|_| Self::UnknownError(status))?;
Err(Self::ResponseError(error_response))
}
}
}
/// Handle the response from a client, but don't parse the JSON body
///
/// Returns an error if any of these steps fail
pub async fn handle_empty(
input: impl Future<Output = Result<ClientResponse<Decoder<Payload<PayloadStream>>>, SendRequestError>>,
) -> Result<(), Self> {
match input.await {
Err(e) => Err(Self::SendError(e)),
Ok(mut response) => {
// Make sure the request is okay
let status = response.status();
if response.status() == StatusCode::OK {
return Ok(());
}
// Otherwise, possibly parse an error response
// If the server didn't return an error response, then just return the status code
let error_response = response
.json::<ErrorResponse>()
.await
.map_err(|_| Self::UnknownError(status))?;
Err(Self::ResponseError(error_response))
}
}
}
}