Skip to content

Commit

Permalink
feat(endpoint_onchain_checkpoints): Error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
akhercha committed May 28, 2024
1 parent d7e2310 commit 4df8344
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 22 deletions.
1 change: 1 addition & 0 deletions pragma-entities/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod schema;
// exporting for idiomatic use
pub use error::{adapt_infra_error, InfraError};
pub use models::{
checkpoint_error::CheckpointError,
currency::Currency,
currency_error::CurrencyError,
entry::{Entry, NewEntry},
Expand Down
52 changes: 52 additions & 0 deletions pragma-entities/src/models/checkpoint_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::Json;
use serde_json::json;

use crate::error::InfraError;

#[derive(Debug, thiserror::Error)]
pub enum CheckpointError {
#[error("internal server error")]
InternalServerError,
#[error("invalid limit : {0}")]
InvalidLimit(u64),
#[error("no checkpoints found for requested pair")]
NotFound(),
}

impl From<InfraError> for CheckpointError {
fn from(error: InfraError) -> Self {
match error {
InfraError::InternalServerError => Self::InternalServerError,
InfraError::NotFound => Self::NotFound(),
InfraError::InvalidTimeStamp => Self::InternalServerError,
}
}
}

impl IntoResponse for CheckpointError {
fn into_response(self) -> axum::response::Response {
let (status, err_msg) = match self {
Self::InvalidLimit(limit) => (
StatusCode::INTERNAL_SERVER_ERROR,
format!("Invalid Limit {}", limit),
),
Self::NotFound() => (
StatusCode::NOT_FOUND,
String::from("No checkpoints found for requested pair"),
),
_ => (
StatusCode::INTERNAL_SERVER_ERROR,
String::from("Internal server error"),
),
};
(
status,
Json(
json!({"resource":"Checkpoint", "message": err_msg, "happened_at" : chrono::Utc::now() }),
),
)
.into_response()
}
}
2 changes: 0 additions & 2 deletions pragma-entities/src/models/entry_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ pub enum EntryError {
PublishData(String),
#[error("can't build publish message: {0}")]
BuildPublish(String),
#[error("limit maximum is 1000, current is: {0}")]
InvalidLimit(u64),
}

impl IntoResponse for EntryError {
Expand Down
1 change: 1 addition & 0 deletions pragma-entities/src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod checkpoint_error;
pub mod currency;
pub mod currency_error;
pub mod entry;
Expand Down
26 changes: 12 additions & 14 deletions pragma-node/src/handlers/entries/get_onchain/checkpoints.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use axum::extract::{Query, State};
use axum::Json;
use pragma_entities::EntryError;
use pragma_entities::CheckpointError;

use crate::handlers::entries::utils::currency_pair_to_pair_id;
use crate::handlers::entries::{GetOnchainCheckpointsParams, GetOnchainCheckpointsResponse};
Expand Down Expand Up @@ -29,23 +29,19 @@ pub async fn get_onchain_checkpoints(
State(state): State<AppState>,
PathExtractor(pair): PathExtractor<(String, String)>,
Query(params): Query<GetOnchainCheckpointsParams>,
) -> Result<Json<GetOnchainCheckpointsResponse>, EntryError> {
) -> Result<Json<GetOnchainCheckpointsResponse>, CheckpointError> {
tracing::info!("Received get onchain entry request for pair {:?}", pair);

let pair_id: String = currency_pair_to_pair_id(&pair.0, &pair.1);
let limit = if let Some(limit) = params.limit {
if (limit == 0) || (limit > MAX_LIMIT) {
// TODO(akhercha): not so great error kind
return Err(EntryError::InvalidLimit(limit));
}
limit
} else {
DEFAULT_LIMIT
};

let limit = params.limit.unwrap_or(DEFAULT_LIMIT);
if !(1..=MAX_LIMIT).contains(&limit) {
return Err(CheckpointError::InvalidLimit(limit));
}

let decimals = get_decimals(&state.timescale_pool, &pair_id)
.await
.map_err(|db_error| db_error.to_entry_error(&pair_id))?;
.map_err(CheckpointError::from)?;

let checkpoints = get_checkpoints(
&state.postgres_pool,
Expand All @@ -55,8 +51,10 @@ pub async fn get_onchain_checkpoints(
limit,
)
.await
.map_err(|db_error| db_error.to_entry_error(&pair_id))?;
.map_err(CheckpointError::from)?;

// TODO(akhercha): Return error if checkpoints length == 0
if checkpoints.is_empty() {
return Err(CheckpointError::NotFound());
}
Ok(Json(GetOnchainCheckpointsResponse(checkpoints)))
}
14 changes: 8 additions & 6 deletions pragma-node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,28 @@ async fn main() {
components(
schemas(pragma_entities::dto::Entry, pragma_entities::EntryError),
schemas(pragma_entities::dto::Publisher, pragma_entities::PublisherError),
schemas(pragma_entities::error::InfraError),
schemas(
handlers::entries::CreateEntryRequest,
handlers::entries::CreateEntryResponse,
handlers::entries::GetEntryParams,
handlers::entries::GetEntryResponse,
handlers::entries::GetVolatilityResponse,
handlers::entries::GetOHLCResponse,
handlers::entries::GetOnchainParams,
handlers::entries::GetOnchainResponse,
handlers::entries::GetOnchainCheckpointsParams,
handlers::entries::GetOnchainCheckpointsResponse,
),
schemas(
handlers::entries::Entry,
handlers::entries::BaseEntry,
handlers::entries::OnchainEntry,
handlers::entries::Checkpoint,
handlers::entries::GetOnchainParams,
handlers::entries::GetOnchainCheckpointsParams
),
schemas(handlers::entries::Checkpoint),
schemas(handlers::entries::Network),
schemas(handlers::entries::AggregationMode),
schemas(handlers::entries::GetEntryParams, handlers::entries::Interval),
schemas(handlers::entries::Entry, handlers::entries::BaseEntry),
schemas(pragma_entities::error::InfraError),
schemas(handlers::entries::Interval),
),
modifiers(&SecurityAddon),
tags(
Expand Down

0 comments on commit 4df8344

Please sign in to comment.