From 702920542d14368c6d0d8f259ee8e3407c358ca7 Mon Sep 17 00:00:00 2001 From: lemarwin Date: Mon, 17 Oct 2022 14:07:54 +0400 Subject: [PATCH] Abstract out and streamline error handling --- hexstody-api/src/domain/error.rs | 152 +++++++++++++++++++ hexstody-api/src/domain/mod.rs | 1 + hexstody-api/src/error.rs | 213 +++++++-------------------- hexstody-operator/src/api/helpers.rs | 3 +- hexstody-operator/src/api/mod.rs | 6 +- hexstody-public/src/api/auth.rs | 2 +- hexstody-public/src/api/mod.rs | 13 +- hexstody-public/src/api/profile.rs | 10 +- hexstody-public/src/api/wallet.rs | 13 +- hexstody-ticker/src/api.rs | 5 +- 10 files changed, 233 insertions(+), 185 deletions(-) create mode 100644 hexstody-api/src/domain/error.rs diff --git a/hexstody-api/src/domain/error.rs b/hexstody-api/src/domain/error.rs new file mode 100644 index 0000000..15e4782 --- /dev/null +++ b/hexstody-api/src/domain/error.rs @@ -0,0 +1,152 @@ +use thiserror::Error; +use crate::domain::{currency::Currency, Erc20Token}; +pub use crate::error::HexstodyError; +pub use crate::error::Result; +pub use crate::error::ErrorMessage; +pub const MIN_USER_NAME_LEN: usize = 3; +pub const MAX_USER_NAME_LEN: usize = 320; +pub const MIN_USER_PASSWORD_LEN: usize = 6; +pub const MAX_USER_PASSWORD_LEN: usize = 1024; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Failed to sign up new user. The user already exists.")] + SignupExistedUser, + #[error( + "Failed to signup user. The user name is too short. Need >= {MIN_USER_NAME_LEN} symbols" + )] + UserNameTooShort, + #[error( + "Failed to signup user. The user name is too long. Need <= {MAX_USER_NAME_LEN} symbols" + )] + UserNameTooLong, + #[error("Failed to signup user. The user password is too short. Need >= {MIN_USER_PASSWORD_LEN} symbols")] + UserPasswordTooShort, + #[error("Failed to signup user. The user password is too long. Need <= {MAX_USER_PASSWORD_LEN} symbols")] + UserPasswordTooLong, + #[error("Password hash failed: {0}")] + Pwhash(#[from] pwhash::error::Error), + #[error("Username of password is invalid")] + SigninFailed, + #[error("Action requires authentification")] + AuthRequired, + #[error("Authed user is not found in state!")] + NoUserFound, + #[error("Authed user doesn't have required currency {0}!")] + NoUserCurrency(Currency), + #[error("Failed to generate new deposit address for currency {0}")] + FailedGenAddress(Currency), + #[error("Failed to get fee for currency {0}")] + FailedGetFee(Currency), + #[error("Not enough {0}!")] + InsufficientFunds(Currency), + #[error("Failed to connect to ETH node: {0}")] + FailedETHConnection(String), + #[error("{0} is already enabled")] + TokenAlreadyEnabled(Erc20Token), + #[error("{0} is already disabled")] + TokenAlreadyDisabled(Erc20Token), + #[error("{0} has non-zero balance. Can not disable")] + TokenNonZeroBalance(Erc20Token), + #[error("Token action failed: {0}")] + TokenActionFailed(String), + #[error("Invite does not exist")] + InviteNotFound, + #[error("Limits are not changed by the update")] + LimitsNoChanges, + #[error("Limit change not found")] + LimChangeNotFound, + #[error("Signature error: {0}")] + SignatureError(String), + #[error("Internal server error: {0}")] + InternalServerError(String), + #[error("Error: {0}")] + GenericError(String), + #[error("Unknown currency: {0}")] + UnknownCurrency(String), + #[error("Language is not changed!")] + LangNotChanged, + #[error("Invalid e-mail")] + InvalidEmail, + #[error("Invalid phone number")] + InvalidPhoneNumber, + #[error("Failed to get {0} exchange rate")] + ExchangeRateError(Currency), + #[error("Malformed margin: {0}")] + MalformedMargin(String), +} + +impl HexstodyError for Error { + fn subtype() -> &'static str { + "hexstody_api" + } + fn code(&self) -> u16 { + match self { + Error::SignupExistedUser => 0, + Error::UserNameTooShort => 1, + Error::UserNameTooLong => 2, + Error::UserPasswordTooShort => 3, + Error::UserPasswordTooLong => 4, + Error::Pwhash(_) => 5, + Error::SigninFailed => 6, + Error::AuthRequired => 7, + Error::NoUserFound => 8, + Error::NoUserCurrency(_) => 9, + Error::FailedGenAddress(_) => 10, + Error::FailedGetFee(_) => 11, + Error::InsufficientFunds(_) => 12, + Error::FailedETHConnection(_) => 13, + Error::TokenAlreadyEnabled(_) => 14, + Error::TokenAlreadyDisabled(_) => 15, + Error::TokenNonZeroBalance(_) => 16, + Error::TokenActionFailed(_) => 17, + Error::InviteNotFound => 18, + Error::LimitsNoChanges => 19, + Error::LimChangeNotFound => 20, + Error::SignatureError(_) => 21, + Error::UnknownCurrency(_) => 22, + Error::InternalServerError(_) => 23, + Error::GenericError(_) => 24, + Error::LangNotChanged => 25, + Error::InvalidEmail => 26, + Error::InvalidPhoneNumber => 27, + Error::ExchangeRateError(_) => 28, + Error::MalformedMargin(_) => 29, + } + } + + fn status(&self) -> u16 { + match self { + Error::SignupExistedUser => 400, + Error::UserNameTooShort => 400, + Error::UserNameTooLong => 400, + Error::UserPasswordTooShort => 400, + Error::UserPasswordTooLong => 400, + Error::Pwhash(_) => 500, + Error::SigninFailed => 401, + Error::AuthRequired => 401, + Error::NoUserFound => 417, + Error::NoUserCurrency(_) => 500, + Error::FailedGenAddress(_) => 500, + Error::FailedGetFee(_) => 500, + Error::InsufficientFunds(_) => 417, + Error::FailedETHConnection(_) => 500, + Error::TokenAlreadyEnabled(_) => 500, + Error::TokenAlreadyDisabled(_) => 500, + Error::TokenNonZeroBalance(_) => 500, + Error::TokenActionFailed(_) => 500, + Error::InviteNotFound => 400, + Error::LimitsNoChanges => 500, + Error::LimChangeNotFound => 400, + Error::SignatureError(_) => 403, + Error::InternalServerError(_) => 500, + Error::GenericError(_) => 500, + Error::UnknownCurrency(_) => 400, + Error::LangNotChanged => 400, + Error::InvalidEmail => 400, + Error::InvalidPhoneNumber => 400, + Error::ExchangeRateError(_) => 404, + Error::MalformedMargin(_) => 400, + } + } +} \ No newline at end of file diff --git a/hexstody-api/src/domain/mod.rs b/hexstody-api/src/domain/mod.rs index d72b238..491b3a2 100644 --- a/hexstody-api/src/domain/mod.rs +++ b/hexstody-api/src/domain/mod.rs @@ -1,4 +1,5 @@ pub mod currency; +pub mod error; use std::str::FromStr; pub use currency::*; diff --git a/hexstody-api/src/error.rs b/hexstody-api/src/error.rs index c9ad0d1..3586cff 100644 --- a/hexstody-api/src/error.rs +++ b/hexstody-api/src/error.rs @@ -1,174 +1,69 @@ -use crate::domain::{currency::Currency, Erc20Token}; -use rocket::http::Status; -use rocket::serde::json::Json; +use std::fmt::Display; + +use okapi::openapi3::Responses; +use rocket::Response; +use rocket::{http::Status, response::Responder}; use rocket_okapi::okapi::schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use thiserror::Error; +use rocket_okapi::response::OpenApiResponderInner; +use rocket_okapi::util::add_schema_response; +use serde::Serialize; +use serde_json::json; -pub const MIN_USER_NAME_LEN: usize = 3; -pub const MAX_USER_NAME_LEN: usize = 320; -pub const MIN_USER_PASSWORD_LEN: usize = 6; -pub const MAX_USER_PASSWORD_LEN: usize = 1024; +pub type Result = std::result::Result; -#[derive(Debug, Error)] -pub enum Error { - #[error("Failed to sign up new user. The user already exists.")] - SignupExistedUser, - #[error( - "Failed to signup user. The user name is too short. Need >= {MIN_USER_NAME_LEN} symbols" - )] - UserNameTooShort, - #[error( - "Failed to signup user. The user name is too long. Need <= {MAX_USER_NAME_LEN} symbols" - )] - UserNameTooLong, - #[error("Failed to signup user. The user password is too short. Need >= {MIN_USER_PASSWORD_LEN} symbols")] - UserPasswordTooShort, - #[error("Failed to signup user. The user password is too long. Need <= {MAX_USER_PASSWORD_LEN} symbols")] - UserPasswordTooLong, - #[error("Password hash failed: {0}")] - Pwhash(#[from] pwhash::error::Error), - #[error("Username of password is invalid")] - SigninFailed, - #[error("Action requires authentification")] - AuthRequired, - #[error("Authed user is not found in state!")] - NoUserFound, - #[error("Authed user doesn't have required currency {0}!")] - NoUserCurrency(Currency), - #[error("Failed to generate new deposit address for currency {0}")] - FailedGenAddress(Currency), - #[error("Failed to get fee for currency {0}")] - FailedGetFee(Currency), - #[error("Not enough {0}!")] - InsufficientFunds(Currency), - #[error("Failed to connect to ETH node: {0}")] - FailedETHConnection(String), - #[error("{0} is already enabled")] - TokenAlreadyEnabled(Erc20Token), - #[error("{0} is already disabled")] - TokenAlreadyDisabled(Erc20Token), - #[error("{0} has non-zero balance. Can not disable")] - TokenNonZeroBalance(Erc20Token), - #[error("Token action failed: {0}")] - TokenActionFailed(String), - #[error("Invite does not exist")] - InviteNotFound, - #[error("Limits are not changed by the update")] - LimitsNoChanges, - #[error("Limit change not found")] - LimChangeNotFound, - #[error("Signature error: {0}")] - SignatureError(String), - #[error("Internal server error: {0}")] - InternalServerError(String), - #[error("Error: {0}")] - GenericError(String), - #[error("Unknown currency: {0}")] - UnknownCurrency(String), - #[error("Language is not changed!")] - LangNotChanged, - #[error("Invalid e-mail")] - InvalidEmail, - #[error("Invalid phone number")] - InvalidPhoneNumber, - #[error("Failed to get {0} exchange rate")] - ExchangeRateError(Currency), - #[error("Malformed margin: {0}")] - MalformedMargin(String), +pub trait HexstodyError { + /// Error subtype, defines concrete error enum: hexstody_api, invoice_api etc + fn subtype() -> &'static str; + /// Internal error code. Paired with subtype uniquely defines the error + fn code(&self) -> u16; + /// Server status code: 400, 403, 500 etc + fn status(&self) -> u16; } -impl Error { - pub fn code(&self) -> u16 { - match self { - Error::SignupExistedUser => 0, - Error::UserNameTooShort => 1, - Error::UserNameTooLong => 2, - Error::UserPasswordTooShort => 3, - Error::UserPasswordTooLong => 4, - Error::Pwhash(_) => 5, - Error::SigninFailed => 6, - Error::AuthRequired => 7, - Error::NoUserFound => 8, - Error::NoUserCurrency(_) => 9, - Error::FailedGenAddress(_) => 10, - Error::FailedGetFee(_) => 11, - Error::InsufficientFunds(_) => 12, - Error::FailedETHConnection(_) => 13, - Error::TokenAlreadyEnabled(_) => 14, - Error::TokenAlreadyDisabled(_) => 15, - Error::TokenNonZeroBalance(_) => 16, - Error::TokenActionFailed(_) => 17, - Error::InviteNotFound => 18, - Error::LimitsNoChanges => 19, - Error::LimChangeNotFound => 20, - Error::SignatureError(_) => 21, - Error::UnknownCurrency(_) => 22, - Error::InternalServerError(_) => 23, - Error::GenericError(_) => 24, - Error::LangNotChanged => 25, - Error::InvalidEmail => 26, - Error::InvalidPhoneNumber => 27, - Error::ExchangeRateError(_) => 28, - Error::MalformedMargin(_) => 29, - } - } - - pub fn status(&self) -> Status { - match self { - Error::SignupExistedUser => Status::from_code(400).unwrap(), - Error::UserNameTooShort => Status::from_code(400).unwrap(), - Error::UserNameTooLong => Status::from_code(400).unwrap(), - Error::UserPasswordTooShort => Status::from_code(400).unwrap(), - Error::UserPasswordTooLong => Status::from_code(400).unwrap(), - Error::Pwhash(_) => Status::from_code(500).unwrap(), - Error::SigninFailed => Status::from_code(401).unwrap(), - Error::AuthRequired => Status::from_code(401).unwrap(), - Error::NoUserFound => Status::from_code(417).unwrap(), - Error::NoUserCurrency(_) => Status::from_code(500).unwrap(), - Error::FailedGenAddress(_) => Status::from_code(500).unwrap(), - Error::FailedGetFee(_) => Status::from_code(500).unwrap(), - Error::InsufficientFunds(_) => Status::from_code(417).unwrap(), - Error::FailedETHConnection(_) => Status::from_code(500).unwrap(), - Error::TokenAlreadyEnabled(_) => Status::from_code(500).unwrap(), - Error::TokenAlreadyDisabled(_) => Status::from_code(500).unwrap(), - Error::TokenNonZeroBalance(_) => Status::from_code(500).unwrap(), - Error::TokenActionFailed(_) => Status::from_code(500).unwrap(), - Error::InviteNotFound => Status::from_code(400).unwrap(), - Error::LimitsNoChanges => Status::from_code(500).unwrap(), - Error::LimChangeNotFound => Status::from_code(400).unwrap(), - Error::SignatureError(_) => Status::from_code(403).unwrap(), - Error::InternalServerError(_) => Status::from_code(500).unwrap(), - Error::GenericError(_) => Status::from_code(500).unwrap(), - Error::UnknownCurrency(_) => Status::from_code(400).unwrap(), - Error::LangNotChanged => Status::from_code(400).unwrap(), - Error::InvalidEmail => Status::from_code(400).unwrap(), - Error::InvalidPhoneNumber => Status::from_code(400).unwrap(), - Error::ExchangeRateError(_) => Status::from_code(404).unwrap(), - Error::MalformedMargin(_) => Status::from_code(400).unwrap(), - } - } -} - -#[derive(Serialize, Deserialize, Debug, JsonSchema)] +#[derive(Debug, Serialize, JsonSchema)] pub struct ErrorMessage { - pub message: String, + /// Internal code of the error. Paired with subtype uniquely defines the error pub code: u16, + /// Subtype + pub subtype: String, + /// Server code of the error: 400, 403, 500 etc + pub status: u16, + /// Error message + pub message: String, } -pub type Result = std::result::Result)>; - -impl From for ErrorMessage { - fn from(value: Error) -> Self { - ErrorMessage { - message: format!("{value}"), - code: value.code(), +impl From for ErrorMessage { + fn from(err: E) -> ErrorMessage { + ErrorMessage { + code: err.code(), + status: err.status(), + message: format!("{err}"), + subtype: E::subtype().to_string() } } } -impl From for (Status, Json) { - fn from(value: Error) -> Self { - (value.status(), Json(value.into())) +impl<'r, 'o: 'r> Responder<'r, 'o> for ErrorMessage { + fn respond_to(self, _: &'r rocket::Request<'_>) -> rocket::response::Result<'o> { + rocket::error_!("[{}:{}]: {}", self.subtype, self.code, self.message); + let resp = json!({ + "id": format!("{}:{}", self.subtype, self.code), + "message": self.message + }); + let resp = serde_json::to_string(&resp).unwrap_or_default(); + Response::build() + .status(Status::from_code(self.code).unwrap_or_default()) + .header(rocket::http::ContentType::JSON) + .sized_body(resp.len(), std::io::Cursor::new(resp)) + .ok() } } + +impl OpenApiResponderInner for ErrorMessage{ + fn responses(gen: &mut rocket_okapi::gen::OpenApiGenerator) -> rocket_okapi::Result { + let mut responses = Responses::default(); + let schema = gen.json_schema::(); + add_schema_response(&mut responses, 200, "application/json", schema.into())?; + Ok(responses) + } +} \ No newline at end of file diff --git a/hexstody-operator/src/api/helpers.rs b/hexstody-operator/src/api/helpers.rs index d4febae..efdea19 100644 --- a/hexstody-operator/src/api/helpers.rs +++ b/hexstody-operator/src/api/helpers.rs @@ -1,8 +1,7 @@ use std::sync::Arc; -use hexstody_api::domain::{CurrencyAddress, EthAccount, BtcAddress, Erc20Token, Erc20}; +use hexstody_api::domain::{error, CurrencyAddress, EthAccount, BtcAddress, Erc20Token, Erc20}; use hexstody_api::{types::SignatureData, domain::Currency}; -use hexstody_api::error; use hexstody_btc_client::client::BtcClient; use hexstody_db::update::{StateUpdate, UpdateBody}; use hexstody_eth_client::client::EthClient; diff --git a/hexstody-operator/src/api/mod.rs b/hexstody-operator/src/api/mod.rs index caba618..4326375 100644 --- a/hexstody-operator/src/api/mod.rs +++ b/hexstody-operator/src/api/mod.rs @@ -21,8 +21,10 @@ use tokio::sync::{mpsc, Mutex, Notify}; use uuid::Uuid; use hexstody_api::{ - domain::Currency, - error, + domain::{ + error, + Currency + }, types::{ ConfirmationData, ConfirmationsConfig, ExchangeAddress, ExchangeBalanceItem, ExchangeConfirmationData, ExchangeFilter, HotBalanceResponse, Invite, InviteRequest, diff --git a/hexstody-public/src/api/auth.rs b/hexstody-public/src/api/auth.rs index 1e52219..6b30b64 100644 --- a/hexstody-public/src/api/auth.rs +++ b/hexstody-public/src/api/auth.rs @@ -1,6 +1,6 @@ use hexstody_api::domain::ChallengeResponse; use hexstody_api::domain::Currency; -use hexstody_api::error; +use hexstody_api::domain::error; use hexstody_api::types as api; use hexstody_api::types::PasswordChange; use hexstody_api::types::SignatureData; diff --git a/hexstody-public/src/api/mod.rs b/hexstody-public/src/api/mod.rs index abf28e6..add58c0 100644 --- a/hexstody-public/src/api/mod.rs +++ b/hexstody-public/src/api/mod.rs @@ -20,7 +20,7 @@ use tokio::sync::{Mutex, Notify}; use rocket::fairing::AdHoc; use rocket::fs::FileServer; -use rocket::http::{CookieJar, Status}; +use rocket::http::CookieJar; use rocket::response::Redirect; use rocket::serde::json::Json; use rocket::uri; @@ -30,8 +30,7 @@ use rocket_okapi::{openapi, openapi_get_routes, swagger_ui::*}; use auth::*; use hexstody_api::{ - domain::{Currency, Language}, - error::{self, ErrorMessage}, + domain::{Currency, Language, error}, types::DepositInfo, }; use hexstody_btc_client::client::BtcClient; @@ -179,7 +178,7 @@ fn signup() -> Template { #[openapi(tag = "auth")] #[get("/logout")] -pub async fn logout(cookies: &CookieJar<'_>) -> Result)> { +pub async fn logout(cookies: &CookieJar<'_>) -> error::Result { let resp = require_auth(cookies, |cookie| async move { cookies.remove(cookie); Ok(Json(())) @@ -189,7 +188,7 @@ pub async fn logout(cookies: &CookieJar<'_>) -> Result Ok(goto_signin()), // Error code 8 => NoUserFound (not logged in). 7 => Requires auth Err(err) => { - if err.1.code == 8 || err.1.code == 7 { + if err.code == 8 || err.code == 7 { Ok(goto_signin()) } else { Err(err) @@ -280,7 +279,7 @@ async fn deposit( Ok(v) => Ok(Ok(v)), // Error code 8 => NoUserFound (not logged in). 7 => Requires auth Err(err) => { - if err.1.code == 8 || err.1.code == 7 { + if err.code == 8 || err.code == 7 { Err(goto_signin()) } else { Ok(Err(err)) @@ -346,7 +345,7 @@ async fn withdraw( Ok(v) => Ok(Ok(v)), // Error code 8 => NoUserFound (not logged in). 7 => Requires auth Err(err) => { - if err.1.code == 8 || err.1.code == 7 { + if err.code == 8 || err.code == 7 { Err(goto_signin()) } else { Ok(Err(err)) diff --git a/hexstody-public/src/api/profile.rs b/hexstody-public/src/api/profile.rs index ed92ceb..d977dca 100644 --- a/hexstody-public/src/api/profile.rs +++ b/hexstody-public/src/api/profile.rs @@ -1,11 +1,11 @@ use std::{sync::Arc, fmt::Debug}; use base64; use hexstody_api::{types::{LimitApiResp, LimitChangeReq, LimitChangeResponse, ConfigChangeRequest, LimitChangeFilter}, domain::{Currency, Language, Email, PhoneNumber, TgName, Unit, CurrencyUnit, UnitInfo, UserUnitInfo}}; -use rocket::{get, http::{CookieJar, Status}, State, serde::json::Json, response::Redirect, post}; +use rocket::{get, http::CookieJar, State, serde::json::Json, response::Redirect, post}; use rocket_okapi::openapi; use tokio::sync::{Mutex, mpsc}; use hexstody_db::{state::{State as DbState, UserConfig}, update::{StateUpdate, limit::{LimitChangeUpd, LimitCancelData}, UpdateBody, misc::{SetLanguage, ConfigUpdateData, SetPublicKey, SetUnit}}}; -use hexstody_api::error; +use hexstody_api::domain::error; use p256::{pkcs8::DecodePublicKey, PublicKey}; use super::auth::{require_auth_user, goto_signin}; @@ -63,7 +63,7 @@ pub async fn request_new_limits( match resp { Ok(v) => Ok(Ok(v)), // Error code 8 => NoUserFound (not logged in). 7 => Requires auth - Err(err) => if err.1.code == 8 || err.1.code == 7 { + Err(err) => if err.code == 8 || err.code == 7 { Err(goto_signin()) } else { Ok(Err(err)) @@ -110,7 +110,7 @@ pub async fn cancel_user_change( match resp { Ok(v) => Ok(Ok(v)), // Error code 8 => NoUserFound (not logged in). 7 => Requires auth - Err(err) => if err.1.code == 8 || err.1.code == 7 { + Err(err) => if err.code == 8 || err.code == 7 { Err(goto_signin()) } else { Ok(Err(err)) @@ -185,7 +185,7 @@ pub async fn set_user_config( }).await } -fn to_generic_error(e: E) -> Result)> +fn to_generic_error(e: E) -> error::Result where E: Debug { diff --git a/hexstody-public/src/api/wallet.rs b/hexstody-public/src/api/wallet.rs index ce89f77..9218c53 100644 --- a/hexstody-public/src/api/wallet.rs +++ b/hexstody-public/src/api/wallet.rs @@ -5,9 +5,8 @@ use super::auth::require_auth_user; use chrono::prelude::*; use hexstody_api::domain::{ filter_tokens, BtcAddress, Currency, CurrencyAddress, CurrencyTxId, ETHTxid, Erc20, Erc20Token, - EthAccount, Symbol, CurrencyUnit, + EthAccount, Symbol, error as error, CurrencyUnit }; -use hexstody_api::error; use hexstody_api::types::{ self as api, BalanceItem, Erc20HistUnitU, ExchangeFilter, ExchangeRequest, GetTokensResponse, TokenActionRequest, TokenInfo, WithdrawalFilter, EthFeeResp, UnitTickedAmount @@ -480,7 +479,7 @@ pub async fn get_deposit_address( state: &State>>, user_id: &str, currency: Currency, -) -> Result { +) -> error::Result { match currency { Currency::BTC => allocate_address(btc_client, eth_client, updater, user_id, currency).await, Currency::ETH | Currency::ERC20(_) => { @@ -509,7 +508,7 @@ async fn allocate_address( updater: &State>, user_id: &str, currency: Currency, -) -> Result { +) -> error::Result { match currency { Currency::BTC => allocate_btc_address(btc_client, updater, user_id).await, Currency::ETH => allocate_eth_address(eth_client, updater, user_id).await, @@ -521,7 +520,7 @@ async fn allocate_btc_address( btc: &State, updater: &State>, user_id: &str, -) -> Result { +) -> error::Result { let address = btc.deposit_address().await.map_err(|e| { error!("{}", e); error::Error::FailedGenAddress(Currency::BTC) @@ -545,7 +544,7 @@ async fn allocate_eth_address( eth_client: &State, updater: &State>, user_id: &str, -) -> Result { +) -> error::Result { let addr = eth_client .allocate_address(&user_id) .await @@ -568,7 +567,7 @@ async fn allocate_erc20_address( updater: &State>, user_id: &str, token: Erc20Token, -) -> Result { +) -> error::Result { let addr = eth_client .allocate_address(&user_id) .await diff --git a/hexstody-ticker/src/api.rs b/hexstody-ticker/src/api.rs index 0c70965..a391bb7 100644 --- a/hexstody-ticker/src/api.rs +++ b/hexstody-ticker/src/api.rs @@ -2,8 +2,9 @@ use std::sync::Arc; use hexstody_api::{ types::{TickerUsdRub, MarginData}, - domain::{Currency, Symbol}}; -use hexstody_api::error; + domain::{Currency, Symbol} +}; +use hexstody_api::domain::error as error; use hexstody_runtime_db::RuntimeState; use hexstody_ticker_provider::client::TickerClient; use rocket::{post, State, Route, serde::json::Json};