Skip to content

Commit 2cd85d6

Browse files
committed
refactor(aggregator-client): reduce boilerplate for error management of get queries
1 parent b3772ac commit 2cd85d6

18 files changed

+92
-138
lines changed

internal/mithril-aggregator-client/src/query/api.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::anyhow;
12
use reqwest::Response;
23
use serde::de::DeserializeOwned;
34
use slog::{Logger, Record, Serializer};
@@ -78,3 +79,32 @@ impl slog::KV for QueryLogFields {
7879
Ok(())
7980
}
8081
}
82+
83+
/// Extension trait for [reqwest::Response] to reduce boilerplate with our library.
84+
#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
85+
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
86+
pub trait ResponseExt {
87+
/// Try to deserialize the response body as JSON, wrapping the error in
88+
/// [AggregatorHttpClientError::JsonParseFailed].
89+
async fn parse_json<T: DeserializeOwned>(self) -> AggregatorHttpClientResult<T>;
90+
91+
/// Try to deserialize the response body as JSON, wrapping a successful result in `Some` and
92+
/// an error in [AggregatorHttpClientError::JsonParseFailed].
93+
async fn parse_json_option<T: DeserializeOwned>(self) -> AggregatorHttpClientResult<Option<T>>;
94+
}
95+
96+
#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
97+
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
98+
impl ResponseExt for Response {
99+
async fn parse_json<T: DeserializeOwned>(self) -> AggregatorHttpClientResult<T> {
100+
let json = self
101+
.json()
102+
.await
103+
.map_err(|err| AggregatorHttpClientError::JsonParseFailed(anyhow!(err)))?;
104+
Ok(json)
105+
}
106+
107+
async fn parse_json_option<T: DeserializeOwned>(self) -> AggregatorHttpClientResult<Option<T>> {
108+
self.parse_json().await.map(Some)
109+
}
110+
}

internal/mithril-aggregator-client/src/query/get/get_aggregator_features.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::AggregatorFeaturesMessage;
65

7-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
8-
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
6+
use crate::AggregatorHttpClientResult;
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
98

109
/// Query to get the features of the aggregator
1110
pub struct GetAggregatorFeaturesQuery {}
@@ -36,11 +35,7 @@ impl AggregatorQuery for GetAggregatorFeaturesQuery {
3635
context: QueryContext,
3736
) -> AggregatorHttpClientResult<Self::Response> {
3837
match context.response.status() {
39-
StatusCode::OK => Ok(context
40-
.response
41-
.json::<AggregatorFeaturesMessage>()
42-
.await
43-
.map_err(|e| AggregatorHttpClientError::JsonParseFailed(anyhow!(e)))?),
38+
StatusCode::OK => context.response.parse_json().await,
4439
_ => Err(context.unhandled_status_code().await),
4540
}
4641
}
@@ -52,6 +47,7 @@ mod tests {
5247

5348
use mithril_common::test::double::Dummy;
5449

50+
use crate::AggregatorHttpClientError;
5551
use crate::test::{assert_error_matches, setup_server_and_client};
5652

5753
use super::*;

internal/mithril-aggregator-client/src/query/get/get_aggregator_status.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::AggregatorStatusMessage;
65

7-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
8-
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
6+
use crate::AggregatorHttpClientResult;
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
98

109
/// Query to get the status of the aggregator
1110
pub struct GetAggregatorStatusQuery {}
@@ -36,11 +35,7 @@ impl AggregatorQuery for GetAggregatorStatusQuery {
3635
context: QueryContext,
3736
) -> AggregatorHttpClientResult<Self::Response> {
3837
match context.response.status() {
39-
StatusCode::OK => Ok(context
40-
.response
41-
.json::<AggregatorStatusMessage>()
42-
.await
43-
.map_err(|e| AggregatorHttpClientError::JsonParseFailed(anyhow!(e)))?),
38+
StatusCode::OK => context.response.parse_json().await,
4439
_ => Err(context.unhandled_status_code().await),
4540
}
4641
}
@@ -52,6 +47,7 @@ mod tests {
5247

5348
use mithril_common::test::double::Dummy;
5449

50+
use crate::AggregatorHttpClientError;
5551
use crate::test::{assert_error_matches, setup_server_and_client};
5652

5753
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_database.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::CardanoDatabaseSnapshotMessage;
65

76
use crate::AggregatorHttpClientResult;
8-
use crate::error::AggregatorHttpClientError;
9-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
108

119
/// Query to get the details of a Cardano database v2 snapshot
1210
pub struct GetCardanoDatabaseQuery {
@@ -39,11 +37,7 @@ impl AggregatorQuery for GetCardanoDatabaseQuery {
3937
context: QueryContext,
4038
) -> AggregatorHttpClientResult<Self::Response> {
4139
match context.response.status() {
42-
StatusCode::OK => match context.response.json::<CardanoDatabaseSnapshotMessage>().await
43-
{
44-
Ok(message) => Ok(Some(message)),
45-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
46-
},
40+
StatusCode::OK => context.response.parse_json_option().await,
4741
StatusCode::NOT_FOUND => Ok(None),
4842
_ => Err(context.unhandled_status_code().await),
4943
}
@@ -56,6 +50,7 @@ mod tests {
5650

5751
use mithril_common::test::double::Dummy;
5852

53+
use crate::error::AggregatorHttpClientError;
5954
use crate::test::{assert_error_matches, setup_server_and_client};
6055

6156
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_database_list.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43
use std::fmt::{Display, Formatter};
54

65
use mithril_common::entities::EpochSpecifier;
76
use mithril_common::messages::CardanoDatabaseSnapshotListMessage;
87

9-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
10-
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
8+
use crate::AggregatorHttpClientResult;
9+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
1110

1211
/// Query to get a list of Cardano database v2 snapshots
1312
pub struct GetCardanoDatabaseListQuery {
@@ -74,12 +73,7 @@ impl AggregatorQuery for GetCardanoDatabaseListQuery {
7473
context: QueryContext,
7574
) -> AggregatorHttpClientResult<Self::Response> {
7675
match context.response.status() {
77-
StatusCode::OK => {
78-
match context.response.json::<CardanoDatabaseSnapshotListMessage>().await {
79-
Ok(message) => Ok(message),
80-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
81-
}
82-
}
76+
StatusCode::OK => context.response.parse_json().await,
8377
_ => Err(context.unhandled_status_code().await),
8478
}
8579
}
@@ -93,6 +87,7 @@ mod tests {
9387
use mithril_common::messages::CardanoDatabaseSnapshotListItemMessage;
9488
use mithril_common::test::double::Dummy;
9589

90+
use crate::AggregatorHttpClientError;
9691
use crate::test::{assert_error_matches, setup_server_and_client};
9792

9893
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_stake_distribution.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43
use std::fmt::{Display, Formatter};
54

65
use mithril_common::entities::EpochSpecifier;
76
use mithril_common::messages::CardanoStakeDistributionMessage;
87

9-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
10-
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
8+
use crate::AggregatorHttpClientResult;
9+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
1110

1211
/// Query to get a Cardano stake distribution
1312
pub struct GetCardanoStakeDistributionQuery {
@@ -72,12 +71,7 @@ impl AggregatorQuery for GetCardanoStakeDistributionQuery {
7271
context: QueryContext,
7372
) -> AggregatorHttpClientResult<Self::Response> {
7473
match context.response.status() {
75-
StatusCode::OK => {
76-
match context.response.json::<CardanoStakeDistributionMessage>().await {
77-
Ok(message) => Ok(Some(message)),
78-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
79-
}
80-
}
74+
StatusCode::OK => context.response.parse_json_option().await,
8175
StatusCode::NOT_FOUND => Ok(None),
8276
_ => Err(context.unhandled_status_code().await),
8377
}
@@ -91,6 +85,7 @@ mod tests {
9185
use mithril_common::entities::Epoch;
9286
use mithril_common::test::double::Dummy;
9387

88+
use crate::AggregatorHttpClientError;
9489
use crate::test::{assert_error_matches, setup_server_and_client};
9590

9691
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_stake_distribution_list.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::CardanoStakeDistributionListMessage;
65

7-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
8-
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
6+
use crate::AggregatorHttpClientResult;
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
98

109
/// Query to get a list of Cardano stake distributions
1110
pub struct GetCardanoStakeDistributionsListQuery {}
@@ -36,12 +35,7 @@ impl AggregatorQuery for GetCardanoStakeDistributionsListQuery {
3635
context: QueryContext,
3736
) -> AggregatorHttpClientResult<Self::Response> {
3837
match context.response.status() {
39-
StatusCode::OK => {
40-
match context.response.json::<CardanoStakeDistributionListMessage>().await {
41-
Ok(message) => Ok(message),
42-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
43-
}
44-
}
38+
StatusCode::OK => context.response.parse_json().await,
4539
_ => Err(context.unhandled_status_code().await),
4640
}
4741
}
@@ -54,6 +48,7 @@ mod tests {
5448
use mithril_common::messages::CardanoStakeDistributionListItemMessage;
5549
use mithril_common::test::double::Dummy;
5650

51+
use crate::AggregatorHttpClientError;
5752
use crate::test::{assert_error_matches, setup_server_and_client};
5853

5954
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_transaction.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::CardanoTransactionSnapshotMessage;
65

76
use crate::AggregatorHttpClientResult;
8-
use crate::error::AggregatorHttpClientError;
9-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
108

119
/// Query to get the details of a Cardano transaction snapshot detail
1210
pub struct GetCardanoTransactionQuery {
@@ -39,12 +37,7 @@ impl AggregatorQuery for GetCardanoTransactionQuery {
3937
context: QueryContext,
4038
) -> AggregatorHttpClientResult<Self::Response> {
4139
match context.response.status() {
42-
StatusCode::OK => {
43-
match context.response.json::<CardanoTransactionSnapshotMessage>().await {
44-
Ok(message) => Ok(Some(message)),
45-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
46-
}
47-
}
40+
StatusCode::OK => context.response.parse_json_option().await,
4841
StatusCode::NOT_FOUND => Ok(None),
4942
_ => Err(context.unhandled_status_code().await),
5043
}
@@ -57,6 +50,7 @@ mod tests {
5750

5851
use mithril_common::test::double::Dummy;
5952

53+
use crate::AggregatorHttpClientError;
6054
use crate::test::{assert_error_matches, setup_server_and_client};
6155

6256
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_transaction_proof.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::CardanoTransactionsProofsMessage;
65

76
use crate::AggregatorHttpClientResult;
8-
use crate::error::AggregatorHttpClientError;
9-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
108

119
/// Query to get a proof of membership for a list of Cardano transaction hashes
1210
pub struct GetCardanoTransactionProofQuery {
@@ -44,12 +42,7 @@ impl AggregatorQuery for GetCardanoTransactionProofQuery {
4442
context: QueryContext,
4543
) -> AggregatorHttpClientResult<Self::Response> {
4644
match context.response.status() {
47-
StatusCode::OK => {
48-
match context.response.json::<CardanoTransactionsProofsMessage>().await {
49-
Ok(message) => Ok(Some(message)),
50-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
51-
}
52-
}
45+
StatusCode::OK => context.response.parse_json_option().await,
5346
StatusCode::NOT_FOUND => Ok(None),
5447
_ => Err(context.unhandled_status_code().await),
5548
}
@@ -60,6 +53,7 @@ impl AggregatorQuery for GetCardanoTransactionProofQuery {
6053
mod tests {
6154
use serde_json::json;
6255

56+
use crate::AggregatorHttpClientError;
6357
use crate::test::{assert_error_matches, setup_server_and_client};
6458

6559
use super::*;

internal/mithril-aggregator-client/src/query/get/get_cardano_transactions_list.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use anyhow::anyhow;
21
use async_trait::async_trait;
32
use reqwest::StatusCode;
43

54
use mithril_common::messages::CardanoTransactionSnapshotListMessage;
65

7-
use crate::query::{AggregatorQuery, QueryContext, QueryMethod};
8-
use crate::{AggregatorHttpClientError, AggregatorHttpClientResult};
6+
use crate::AggregatorHttpClientResult;
7+
use crate::query::{AggregatorQuery, QueryContext, QueryMethod, ResponseExt};
98

109
/// Query to get a list of Cardano transactions snapshots
1110
pub struct GetCardanoTransactionsListQuery {}
@@ -36,12 +35,7 @@ impl AggregatorQuery for GetCardanoTransactionsListQuery {
3635
context: QueryContext,
3736
) -> AggregatorHttpClientResult<Self::Response> {
3837
match context.response.status() {
39-
StatusCode::OK => {
40-
match context.response.json::<CardanoTransactionSnapshotListMessage>().await {
41-
Ok(message) => Ok(message),
42-
Err(err) => Err(AggregatorHttpClientError::JsonParseFailed(anyhow!(err))),
43-
}
44-
}
38+
StatusCode::OK => context.response.parse_json().await,
4539
_ => Err(context.unhandled_status_code().await),
4640
}
4741
}
@@ -54,6 +48,7 @@ mod tests {
5448
use mithril_common::messages::CardanoTransactionSnapshotListItemMessage;
5549
use mithril_common::test::double::Dummy;
5650

51+
use crate::AggregatorHttpClientError;
5752
use crate::test::{assert_error_matches, setup_server_and_client};
5853

5954
use super::*;

0 commit comments

Comments
 (0)