Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: revamp provider error handling #511

Merged
merged 1 commit into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions starknet-accounts/src/factory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use starknet_core::{
SimulationFlag, StarknetError,
},
};
use starknet_providers::{
MaybeUnknownErrorCode, Provider, ProviderError, StarknetErrorWithMessage,
};
use starknet_providers::{Provider, ProviderError};
use std::error::Error;

pub mod argent;
Expand Down Expand Up @@ -178,10 +176,9 @@ where
.await
{
Ok(nonce) => Ok(nonce),
Err(ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::ContractNotFound),
..
})) => Ok(FieldElement::ZERO),
Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => {
Ok(FieldElement::ZERO)
}
Err(err) => Err(err),
}
}
Expand Down
35 changes: 34 additions & 1 deletion starknet-core/src/types/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen

// Code generated with version:
// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen#3215ab04aee89aafa48973cdcf027219f662f49d
// https://github.com/xJonathanLEI/starknet-jsonrpc-codegen#51260963a0723fdbc715598efb7198ce5a1d49b9

// Code generation requested but not implemented for these types:
// - `BLOCK_ID`
Expand Down Expand Up @@ -1397,6 +1397,39 @@ impl core::fmt::Display for StarknetError {
}
}

impl StarknetError {
pub fn message(&self) -> &'static str {
match self {
Self::FailedToReceiveTransaction => "Failed to write transaction",
Self::ContractNotFound => "Contract not found",
Self::BlockNotFound => "Block not found",
Self::InvalidTransactionIndex => "Invalid transaction index in a block",
Self::ClassHashNotFound => "Class hash not found",
Self::TransactionHashNotFound => "Transaction hash not found",
Self::PageSizeTooBig => "Requested page size is too big",
Self::NoBlocks => "There are no blocks",
Self::InvalidContinuationToken => "The supplied continuation token is invalid or unknown",
Self::TooManyKeysInFilter => "Too many keys provided in a filter",
Self::ContractError => "Contract error",
Self::ClassAlreadyDeclared => "Class already declared",
Self::InvalidTransactionNonce => "Invalid transaction nonce",
Self::InsufficientMaxFee => "Max fee is smaller than the minimal transaction cost (validation plus fee transfer)",
Self::InsufficientAccountBalance => "Account balance is smaller than the transaction's max_fee",
Self::ValidationFailure => "Account validation failed",
Self::CompilationFailed => "Compilation failed",
Self::ContractClassSizeIsTooLarge => "Contract class size it too large",
Self::NonAccount => "Sender address in not an account contract",
Self::DuplicateTx => "A transaction with the same hash already exists in the mempool",
Self::CompiledClassHashMismatch => "the compiled class hash did not match the one supplied in the transaction",
Self::UnsupportedTxVersion => "the transaction version is not supported",
Self::UnsupportedContractClassVersion => "the contract class version is not supported",
Self::UnexpectedError => "An unexpected error occurred",
Self::NoTraceAvailable => "No trace available for transaction",
Self::InvalidTransactionHash => "Invalid transaction hash",
}
}
}

/// The change in state applied in this block, given as a mapping of addresses to the new values
/// and/or new contracts.
#[serde_as]
Expand Down
32 changes: 8 additions & 24 deletions starknet-providers/src/jsonrpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ use starknet_core::{
EventFilterWithPage, EventsPage, FeeEstimate, FieldElement, FunctionCall,
InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs,
MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1, ResultPageRequest,
SimulatedTransaction, SimulationFlag, StarknetError, SyncStatusType, Transaction,
TransactionStatus, TransactionTrace, TransactionTraceWithHash,
SimulatedTransaction, SimulationFlag, SyncStatusType, Transaction, TransactionStatus,
TransactionTrace, TransactionTraceWithHash,
},
};

use crate::{
provider::{MaybeUnknownErrorCode, ProviderImplError, StarknetErrorWithMessage},
Provider, ProviderError,
};
use crate::{provider::ProviderImplError, Provider, ProviderError};

mod transports;
pub use transports::{HttpTransport, HttpTransportError, JsonRpcTransport};
Expand Down Expand Up @@ -135,15 +132,7 @@ pub enum JsonRpcClientError<T> {
#[error(transparent)]
TransportError(T),
#[error(transparent)]
RpcError(RpcError),
}

#[derive(Debug, thiserror::Error)]
pub enum RpcError {
#[error(transparent)]
Code(StarknetError),
#[error(transparent)]
Unknown(JsonRpcError),
JsonRpcError(JsonRpcError),
}

#[derive(Debug, thiserror::Error, Deserialize)]
Expand Down Expand Up @@ -190,15 +179,10 @@ where
.map_err(JsonRpcClientError::TransportError)?
{
JsonRpcResponse::Success { result, .. } => Ok(result),
JsonRpcResponse::Error { error, .. } => {
Err(ProviderError::StarknetError(StarknetErrorWithMessage {
code: match error.code.try_into() {
Ok(code) => MaybeUnknownErrorCode::Known(code),
Err(_) => MaybeUnknownErrorCode::Unknown(error.code),
},
message: error.message,
}))
}
JsonRpcResponse::Error { error, .. } => Err(match error.code.try_into() {
Ok(code) => ProviderError::StarknetError(code),
Err(_) => JsonRpcClientError::<T::Error>::JsonRpcError(error).into(),
}),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion starknet-providers/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![doc = include_str!("../README.md")]

mod provider;
pub use provider::{MaybeUnknownErrorCode, Provider, ProviderError, StarknetErrorWithMessage};
pub use provider::{Provider, ProviderError};

pub mod sequencer;
pub use sequencer::{
Expand Down
24 changes: 1 addition & 23 deletions starknet-providers/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,33 +297,11 @@ pub trait ProviderImplError: Error + Debug + Send + Sync {
#[derive(Debug, thiserror::Error)]
pub enum ProviderError {
#[error(transparent)]
StarknetError(StarknetErrorWithMessage),
StarknetError(StarknetError),
#[error("Request rate limited")]
RateLimited,
#[error("Array length mismatch")]
ArrayLengthMismatch,
#[error("{0}")]
Other(Box<dyn ProviderImplError>),
}

#[derive(Debug, thiserror::Error)]
#[error("code={code}, message=\"{message}\"")]
pub struct StarknetErrorWithMessage {
pub code: MaybeUnknownErrorCode,
pub message: String,
}

#[derive(Debug)]
pub enum MaybeUnknownErrorCode {
Known(StarknetError),
Unknown(i64),
}

impl core::fmt::Display for MaybeUnknownErrorCode {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
MaybeUnknownErrorCode::Known(code) => write!(f, "{}", code),
MaybeUnknownErrorCode::Unknown(code) => write!(f, "{}", code),
}
}
}
7 changes: 2 additions & 5 deletions starknet-providers/src/sequencer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::provider::{MaybeUnknownErrorCode, ProviderError, StarknetErrorWithMessage};
use crate::provider::ProviderError;

use log::trace;
use reqwest::{Client, Error as ReqwestError, StatusCode};
Expand Down Expand Up @@ -730,10 +730,7 @@ impl From<SequencerError> for ProviderError {
};

match matching_code {
Some(code) => ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(code),
message: value.message,
}),
Some(code) => ProviderError::StarknetError(code),
None => GatewayClientError::SequencerError(value).into(),
}
}
Expand Down
23 changes: 10 additions & 13 deletions starknet-providers/src/sequencer/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use starknet_core::types::{
};

use crate::{
provider::{MaybeUnknownErrorCode, ProviderImplError, StarknetErrorWithMessage},
provider::ProviderImplError,
sequencer::{
models::conversions::{ConversionError, TransactionWithReceipt},
GatewayClientError,
Expand Down Expand Up @@ -106,10 +106,9 @@ impl Provider for SequencerGatewayProvider {

// `NotReceived` is not a valid status for JSON-RPC. It's an error.
if let Some(TransactionFinalityStatus::NotReceived) = &status.finality_status {
return Err(ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound),
message: "Transaction hash not found".into(),
}));
return Err(ProviderError::StarknetError(
StarknetError::TransactionHashNotFound,
));
}

Ok(status.try_into()?)
Expand Down Expand Up @@ -142,10 +141,9 @@ impl Provider for SequencerGatewayProvider {
if index < block.transactions.len() {
Ok(block.transactions.remove(index).try_into()?)
} else {
Err(ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::InvalidTransactionIndex),
message: "Invalid transaction index in a block".into(),
}))
Err(ProviderError::StarknetError(
StarknetError::InvalidTransactionIndex,
))
}
}

Expand All @@ -164,10 +162,9 @@ impl Provider for SequencerGatewayProvider {
if receipt.status == super::models::TransactionStatus::NotReceived
|| receipt.status == super::models::TransactionStatus::Received
{
Err(ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound),
message: "Transaction hash not found".into(),
}))
Err(ProviderError::StarknetError(
StarknetError::TransactionHashNotFound,
))
} else {
// JSON-RPC also sends tx type, which is not available in our receipt type
let tx = self.get_transaction(*transaction_hash.as_ref()).await?;
Expand Down
7 changes: 2 additions & 5 deletions starknet-providers/tests/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use starknet_core::{
};
use starknet_providers::{
jsonrpc::{HttpTransport, JsonRpcClient},
MaybeUnknownErrorCode, Provider, ProviderError, StarknetErrorWithMessage,
Provider, ProviderError,
};
use url::Url;

Expand Down Expand Up @@ -371,10 +371,7 @@ async fn jsonrpc_get_transaction_by_hash_non_existent_tx() {
.unwrap_err();

match err {
ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound),
..
}) => {
ProviderError::StarknetError(StarknetError::TransactionHashNotFound) => {
// TXN_HASH_NOT_FOUND
}
_ => panic!("Unexpected error"),
Expand Down
Loading