-
Notifications
You must be signed in to change notification settings - Fork 14
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
Rpc failures #58
Rpc failures #58
Conversation
WalkthroughThe changes in this pull request focus on enhancing error handling within the Changes
Possibly related PRs
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
crates/core/src/interpreter/backend/resolve_account.rs (3)
74-80
: LGTM: Robust error handling for balance fetchThe error handling is well-implemented, logging the error while allowing the operation to continue by setting
balance
toNone
.Consider enhancing the error message to include the chain information:
-error!("Failed to fetch balance for address {}: {:?}", address, e); +error!("Failed to fetch balance for address {} on chain {:?}: {:?}", address, chain, e);
83-89
: Consider more granular error handling for different RPC failure typesWhile the current error handling is good, consider distinguishing between different types of RPC failures (e.g., network timeouts vs contract errors) for more targeted error handling and potential retries.
Example enhancement:
match provider.get_transaction_count(*address).await { Ok(nonce) => account.nonce = Some(nonce), Err(e) => { - error!("Failed to fetch nonce for address {}: {:?}", address, e); + match e { + ProviderError::RpcError(rpc_err) => { + error!("RPC error fetching nonce for {}: {:?}", address, rpc_err); + // Potentially retry for certain RPC errors + } + ProviderError::NetworkError(net_err) => { + error!("Network error fetching nonce for {}: {:?}", address, net_err); + // Potentially retry for network errors + } + _ => error!("Unknown error fetching nonce for {}: {:?}", address, e), + } account.nonce = None; } }Also applies to: 95-101
74-104
: Consider adding structured error reporting for partial failuresWhile the current implementation gracefully handles failures by setting fields to
None
, it might be helpful to provide more detailed error information to the caller.Consider adding an errors field to
AccountQueryRes
to track which fields failed and why:pub struct AccountQueryRes { // ... existing fields ... pub field_errors: HashMap<AccountField, String>, // Track errors per field }This would allow callers to:
- Distinguish between missing data (None) and failed fetches
- Make informed decisions about retrying specific fields
- Provide better error reporting to end users
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
crates/core/src/interpreter/backend/resolve_account.rs
(2 hunks)
🔇 Additional comments (2)
crates/core/src/interpreter/backend/resolve_account.rs (2)
60-61
: LGTM: Appropriate logging import added
The addition of log::error
is appropriate for the new error handling functionality.
74-104
: Verify consistent error handling across other RPC calls
Let's ensure this error handling pattern is consistently applied across all RPC calls in the codebase.
✅ Verification successful
Based on the search results, I can now generate the final response:
Error handling is consistently implemented across RPC calls
The codebase shows consistent error handling patterns across all RPC calls:
- All
provider
RPC calls use proper error handling withmatch
or?
operator - No instances of
.unwrap()
were found on RPC results - Other modules (
resolve_block.rs
,resolve_logs.rs
,chain.rs
) properly propagate errors using the?
operator
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other direct RPC calls that might need similar error handling
rg -A 2 "provider\.(get_|call|send)" --type rust
# Search for potential unwrap calls on RPC results
ast-grep --pattern 'provider.$_($$$).await.unwrap()'
Length of output: 2282
Hey @Krishn1412, will review this first thing tomorrow. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good and does exactly what needs to do :)
Just small tweaks and we'll be able to include this in the next release
I have made the changes, @iankressin can you take a look again? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (1)
crates/core/src/interpreter/backend/resolve_account.rs (1)
74-95
: Consider batching RPC calls for better performanceThe current implementation makes separate RPC calls for each field. While this provides good isolation (a failure in one field doesn't affect others), it might not be optimal for performance, especially when fetching multiple fields.
Consider:
- Using batch RPC calls where the provider supports it
- Implementing concurrent requests for providers that don't support batching
- Adding a configuration option to trade off between performance (batched) and reliability (separate calls)
Would you like help implementing any of these suggestions?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
crates/core/src/interpreter/backend/resolve_account.rs
(2 hunks)
🔇 Additional comments (1)
crates/core/src/interpreter/backend/resolve_account.rs (1)
60-60
: Remove unused import
The log::error
import is not used in the current changes. Additionally, as per previous feedback, we should avoid console output as it affects REPL formatting. Consider removing this import until we implement the suggested --debug
flag feature.
-use log::error;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Krishn1412 just remove the unused import, everything else looks good
@iankressin I have removed the unused imports. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (2)
crates/core/src/interpreter/backend/resolve_account.rs (2)
72-93
: Consider implementing robust RPC failure handling strategyWhile the current changes prevent panics, a production-ready RPC interaction strategy should consider:
- Retries with exponential backoff for transient failures
- Timeouts to prevent hanging on slow responses
- Circuit breakers for failing nodes
- Fallback providers for critical operations
Consider implementing a wrapper around the provider that handles these concerns:
pub struct RobustProvider { provider: RootProvider<Http<Client>>, retry_config: RetryConfig, timeout: Duration, } impl RobustProvider { async fn with_retry<T, F>(&self, operation: F) -> Result<T> where F: Fn() -> Future<Output = Result<T>>, { // Implementation with retry logic, timeouts, etc. } }Would you like me to create an issue to track this enhancement?
72-93
: Add documentation for RPC failure handling behaviorThe changes improve RPC failure handling, but the behavior should be documented:
- Update function documentation to describe error handling behavior
- Add examples of how RPC failures are handled
- Consider adding integration tests that simulate RPC failures
Add documentation above the
get_account
function:/// Fetches account data from the provider, handling RPC failures gracefully. /// /// # Error Handling /// - If an RPC call fails, the corresponding field will be set to None /// - The function will continue to fetch other requested fields even if some calls fail /// /// # Examples /// ```rust /// // Example of handling RPC failure for balance /// let account = get_account(&address, vec![AccountField::Balance], &failing_provider, &chain).await?; /// assert!(account.balance.is_none()); // Balance is None when RPC fails /// ```
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
crates/core/src/interpreter/backend/resolve_account.rs
(1 hunks)
🔇 Additional comments (2)
crates/core/src/interpreter/backend/resolve_account.rs (2)
72-76
: Consider using helper function for error handling pattern
This error handling pattern is duplicated across multiple fields. Previous review suggestions for using a helper function and adding debug logging capability still apply.
89-93
: 🛠️ Refactor suggestion
Distinguish between empty code and RPC failures
The current implementation treats RPC failures the same as accounts with no code (EOAs). Consider distinguishing between these cases, as they have different semantic meanings:
- RPC failure: temporary infrastructure issue
- Empty code (0x): confirms this is an EOA (Externally Owned Account)
Consider this approach:
-if let Ok(code) = provider.get_code_at(*address).await {
- account.code = Some(code);
-} else {
- account.code = None;
-}
+match provider.get_code_at(*address).await {
+ Ok(code) => {
+ // Only set Some if there's actual code
+ account.code = if code.is_empty() { None } else { Some(code) };
+ }
+ Err(_) => {
+ // Indicate RPC failure differently than empty code
+ account.code = None;
+ // TODO: Once we have the --debug flag:
+ // log::debug!("Failed to fetch code: {}", e);
+ }
+}
Likely invalid or redundant comment.
Thanks @Krishn1412 |
Summary
Related Issue
Technical details
Topics for Discussion
PR Checklist
Screenshots (if applicable)
Summary by CodeRabbit
None
when errors occur, ensuring smoother operation.These changes ensure a more stable user experience by allowing the application to continue functioning smoothly even when individual account queries encounter issues.