Skip to content
This repository has been archived by the owner on Jul 17, 2023. It is now read-only.

Commit

Permalink
TEAS-577 [feat] allow error_handler to return future
Browse files Browse the repository at this point in the history
  • Loading branch information
untoldwind committed Dec 5, 2018
1 parent 5019243 commit 5c105b9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
7 changes: 5 additions & 2 deletions src/service_requester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn encode_url_component<S: AsRef<[u8]>>(value: S) -> String {
#[derive(Clone)]
pub struct ServiceRequester {
token_creator: Addr<gatekeeper::TokenCreator>,
error_handler: &'static (Fn(client::ClientResponse) -> Problem + Sync),
error_handler: &'static (Fn(client::ClientResponse) -> Box<Future<Item = Problem, Error = Problem>> + Sync),
}

pub trait IntoClientRequest {
Expand All @@ -30,7 +30,10 @@ impl ServiceRequester {
}
}

pub fn with_error_handler(&self, error_handler: &'static (Fn(client::ClientResponse) -> Problem + Sync)) -> Self {
pub fn with_error_handler(
&self,
error_handler: &'static (Fn(client::ClientResponse) -> Box<Future<Item = Problem, Error = Problem>> + Sync),
) -> Self {
ServiceRequester {
token_creator: self.token_creator.clone(),
error_handler,
Expand Down
29 changes: 22 additions & 7 deletions src/ws_try.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use actix_web::client;
use actix_web::HttpMessage;
use business_result::AsyncBusinessResult;
use futures::{Future, Poll, Stream};
use futures::{future, Async, Future, Poll, Stream};
use problem::Problem;
use serde::de::DeserializeOwned;
use std::time::Duration;
Expand All @@ -23,6 +23,7 @@ pub trait FromClientResponse {
pub enum WSTry<F> {
MayBeSuccess(F),
Failure(Problem),
FutureFailure(Box<Future<Item = Problem, Error = Problem>>),
}

impl<T, F> Future for WSTry<F>
Expand All @@ -36,6 +37,11 @@ where
match self {
WSTry::MayBeSuccess(f) => f.poll(),
WSTry::Failure(problem) => Err(problem.clone()),
WSTry::FutureFailure(future_problem) => match future_problem.poll() {
Ok(Async::NotReady) => Ok(Async::NotReady),
Ok(Async::Ready(problem)) => Err(problem),
Err(problem) => Err(problem),
},
}
}
}
Expand Down Expand Up @@ -70,31 +76,40 @@ where
T: FromClientResponse<Result = T, FutureResult = F>,
F: Future<Item = T, Error = Problem>,
{
expect_success_with_error(request, default_error_handler)
try(request).and_then(move |resp| {
if resp.status().is_success() {
WSTry::MayBeSuccess(T::from_response(resp))
} else {
WSTry::Failure(Problem::for_status(
resp.status().as_u16(),
format!("Service request failed: {}", resp.status()),
))
}
})
}

pub fn expect_success_with_error<R, F, T, E>(request: R, error_handler: E) -> impl Future<Item = T, Error = Problem>
where
R: IntoClientRequest,
T: FromClientResponse<Result = T, FutureResult = F>,
F: Future<Item = T, Error = Problem>,
E: Fn(client::ClientResponse) -> Problem,
E: Fn(client::ClientResponse) -> Box<Future<Item = Problem, Error = Problem>>,
{
try(request).and_then(move |resp| {
if resp.status().is_success() {
WSTry::MayBeSuccess(T::from_response(resp))
} else {
WSTry::Failure(error_handler(resp))
WSTry::FutureFailure(error_handler(resp))
}
})
}

#[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))]
pub fn default_error_handler(response: client::ClientResponse) -> Problem {
Problem::for_status(
pub fn default_error_handler(response: client::ClientResponse) -> Box<Future<Item = Problem, Error = Problem>> {
Box::new(future::ok(Problem::for_status(
response.status().as_u16(),
format!("Service request failed: {}", response.status()),
)
)))
}

impl IntoClientRequest for client::ClientRequest {
Expand Down

0 comments on commit 5c105b9

Please sign in to comment.