Skip to content

Conversation

@hewigovens
Copy link
Owner

@hewigovens hewigovens commented Jun 7, 2025

Summary by CodeRabbit

  • New Features

    • Introduced unified error handling with a new public error type for improved error reporting.
    • Added support for custom authentication methods, including API key header authentication.
    • Enabled optional request timeouts and middleware support for HTTP providers.
  • Bug Fixes

    • Enhanced error propagation for body serialization and request building, reducing unexpected panics.
  • Refactor

    • Updated trait and struct method signatures to use owned String types and Result for better flexibility and error handling.
    • Removed feature gating on JSON-RPC support, making related functionality always available.
  • Documentation

    • Added detailed crate-level documentation describing features, usage, and configuration.
  • Tests

    • Expanded test coverage to include new authentication methods and updated error handling logic.
  • Chores

    • Updated CI configuration and test commands to improve build and test processes.

@semanticdiff-com
Copy link

semanticdiff-com bot commented Jun 7, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  reqwest-enum/src/target.rs  51% smaller
  reqwest-enum/src/provider.rs  32% smaller
  reqwest-enum/src/http.rs  29% smaller
  examples/ethereum-rpc/src/ethereum_rpc.rs  16% smaller
  reqwest-enum/src/jsonrpc.rs  5% smaller
  .github/workflows/ci.yml  0% smaller
  Cargo.lock Unsupported file format
  Cargo.toml Unsupported file format
  Justfile Unsupported file format
  reqwest-enum/Cargo.toml Unsupported file format
  reqwest-enum/src/error.rs  0% smaller
  reqwest-enum/src/lib.rs  0% smaller

@hewigovens hewigovens requested a review from Copilot June 7, 2025 12:45
@coderabbitai
Copy link

coderabbitai bot commented Jun 7, 2025

Walkthrough

This update advances the reqwest-enum crate by introducing a unified error enum, fallible HTTP body serialization, owned string APIs for targets, flexible authentication including custom closures, optional request timeouts, middleware support, and enhanced JSON-RPC error handling. It also updates example usage and testing accordingly.

Changes

File(s) Change Summary
Cargo.toml Updated workspace version to "0.4.0" and Rust edition to "2024". Added Tokio runtime dependency with macros and multi-thread features.
reqwest-enum/Cargo.toml Added middleware feature with optional reqwest-middleware dependency; added mandatory thiserror dependency; replaced tokio-test dev-dependency with workspace tokio.
reqwest-enum/src/error.rs Added public Error enum unifying errors from reqwest, reqwest-middleware (optional), and serde_json with thiserror integration.
reqwest-enum/src/lib.rs Added crate-level documentation; introduced public error module and re-exported Error.
reqwest-enum/src/http.rs Made HTTPBody::from and from_array fallible returning Result; changed AuthMethod variants to own Strings; added Custom variant with closure for auth; added header_api_key helper; implemented manual Debug for AuthMethod.
reqwest-enum/src/jsonrpc.rs Removed all #[cfg(feature = "jsonrpc")] gating, making JSON-RPC types always included; added From<crate::Error> for JsonRpcError with detailed variant mapping; removed From<JsonRpcRequest> for HTTPBody.
reqwest-enum/src/provider.rs Added optional timeout field; conditionally compiled client with or without middleware; changed request_builder to return Result; applied new auth including Custom; refactored JSON-RPC batch handling with error propagation; updated constructors; exposed request_url; updated tests for new API and added header API key auth test.
reqwest-enum/src/target.rs Changed Target trait methods to return owned String and HashMap<String, String>; added authentication method returning Option<AuthMethod>; made body fallible returning Result; removed timeout method; updated imports and helpers accordingly.
examples/ethereum-rpc/src/ethereum_rpc.rs Updated EthereumRPC Target impl to use owned String and HashMap<String, String>; made body fallible returning Result; removed timeout; cleaned imports.
.github/workflows/ci.yml Added blank line after cache key; changed SCCACHE_GHA_ENABLED env var from "true" to "false".
Justfile Modified test recipe to run cargo test with --all-features instead of --verbose.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Provider
    participant Target
    participant ReqwestClient
    participant Middleware as ClientWithMiddleware
    participant Error

    User->>Provider: new(..., timeout, ...)
    User->>Provider: request(target)
    Provider->>Target: base_url(), path(), query(), headers(), authentication(), body()
    Target-->>Provider: String, HashMap<String, String>, Option<AuthMethod>, Result<HTTPBody, Error>
    Provider->>ReqwestClient: build RequestBuilder (or Middleware)
    ReqwestClient-->>Provider: RequestBuilder
    Provider->>ReqwestClient: execute request
    ReqwestClient-->>Provider: Result<Response, reqwest::Error>
    Provider-->>User: Result<Response, Error>
Loading

Poem

A hop and a leap, a new error to keep,
Strings now abound where statics would sleep.
Custom auth keys, and timeouts that wait,
Middleware joins in—oh, isn’t that great?
With fallible bodies, our code’s more robust—
This rabbit approves, in these changes we trust!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @hewigovens, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

Gemini or gemini-code-assist here, providing a summary for this pull request. This PR introduces support for reqwest-middleware to the reqwest-enum library, allowing users to add middleware layers to their HTTP clients. It also includes significant improvements to error handling by introducing a custom Error enum using thiserror, enhances the flexibility of the Target trait by allowing String for URLs, queries, and headers, and adds a custom authentication method. The library version is bumped to 0.4.0 to reflect these changes.

Highlights

  • Middleware Support: Adds an optional middleware feature that integrates reqwest-middleware, enabling users to chain middleware layers for requests.
  • Improved Error Handling: Introduces a new Error enum using thiserror to provide more structured and informative error reporting, wrapping underlying reqwest, reqwest-middleware, and serde_json errors.
  • Flexible Target Trait: Updates the Target trait to use String for base_url, query, and headers, removing the 'static lifetime constraint. The body method now returns a Result to handle potential serialization errors, and the timeout method has been removed from the trait (timeout is now handled at the Provider level).
  • Custom Authentication Method: Adds a new AuthMethod::Custom variant and a helper header_api_key function to allow more flexible authentication logic.
  • Version Bump: The library version is updated from 0.3.3 to 0.4.0, indicating breaking changes due to the trait and API modifications.

Changelog

Click here to see the changelog
  • Cargo.lock
    • Added new dependencies: anyhow (1.0.98), async-trait (0.1.88), reqwest-middleware (0.4.2), thiserror (1.0.69, 2.0.12), thiserror-impl (1.0.69, 2.0.12).
    • Updated existing dependencies: ethereum-rpc (0.3.3 -> 0.4.0), reqwest-enum (0.3.3 -> 0.4.0), syn (2.0.79 -> 2.0.87).
  • Cargo.toml
    • Updated workspace version to 0.4.0 and edition to 2024.
    • Added middleware feature depending on reqwest-middleware.
    • Added thiserror = "2.0.12" as a dependency.
    • Added reqwest-middleware = { version = "0.4.2", optional = true } as a dependency.
  • examples/ethereum-rpc/src/ethereum_rpc.rs
    • Removed unused extern crate and Duration import (lines 1-2, 10).
    • Changed base_url return type in Target impl from &'static str to String (line 144).
    • Changed query and headers return types in Target impl from HashMap<&'static str, &'static str> to HashMap<String, String> (lines 156, 160).
    • Changed body return type in Target impl from HTTPBody to Result<HTTPBody, reqwest_enum::Error> and updated implementation to use HTTPBody::from which now returns a Result (line 170).
    • Removed timeout method implementation from Target trait (lines 177-180).
  • reqwest-enum/Cargo.toml
    • Added thiserror and reqwest-middleware dependencies (lines 20, 26).
    • Added middleware feature (line 17).
  • reqwest-enum/src/error.rs
    • Added a new file defining the Error enum using thiserror (lines 1-15).
  • reqwest-enum/src/http.rs
    • Changed HTTPBody::from and from_array methods to return Result<Self, serde_json::Error> (lines 59, 65).
    • Changed AuthMethod::Basic variant to accept String and Option<String> (line 74).
    • Added AuthMethod::Custom variant for custom authentication logic (line 78).
    • Added AuthMethod::header_api_key helper function (lines 81-88).
    • Implemented Debug for AuthMethod (lines 91-102).
  • reqwest-enum/src/jsonrpc.rs
    • Removed #[cfg(feature = "jsonrpc")] attributes from JsonRpcRequest, JsonRpcResponse, JsonRpcErrorResponse, JsonRpcError, JsonRpcId structs/enums and their implementations (lines 4, 14, 40, 49, 57, 64, 67, 83, 91).
    • Removed From<JsonRpcRequest> for HTTPBody implementation (lines 33-38).
    • Added From<crate::Error> for JsonRpcError implementation to convert the new library error type (lines 60-77).
  • reqwest-enum/src/lib.rs
    • Added error module declaration and re-exported Error (lines 1-2).
  • reqwest-enum/src/provider.rs
    • Imported Error from crate root (line 12).
    • Imported Duration (line 13).
    • Conditionally imported ClientWithMiddleware and MiddlewareClientBuilder based on middleware feature (lines 17-18).
    • Updated Provider struct to include timeout field and use ClientWithMiddleware conditionally (lines 57-61).
    • Updated ProviderType::request implementation to handle Result from target.body() and use the client's execute method (lines 68-71).
    • Updated JsonRpcProviderType::batch and batch_chunk_by implementations to handle Result from HTTPBody::from_array and use the client's execute method (lines 116, 123, 127, 159, 164).
    • Updated Provider::new and added with_client methods to handle the conditional middleware client and the new timeout parameter (lines 194-239).
    • Changed request_builder to return Result<reqwest::RequestBuilder, Error> and moved body serialization and timeout application into this method (lines 249-286).
    • Updated Default implementation for Provider to handle the conditional middleware client and timeout (lines 294-305).
    • Updated test cases (test_request_builder_with_endpoint_fn, test_request_builder_with_request_fn) to match the new Provider::new signature and request_builder return type (lines 407, 425, 428).
    • Added HeaderAuth variant to HttpBin enum for testing custom header authentication (line 334).
    • Updated Target impl for HttpBin to handle HeaderAuth (lines 347, 360, 385).
    • Added AuthMethod::header_api_key usage in HttpBin::authentication for HeaderAuth (lines 375-378).
    • Added test_header_api_key_auth test case (lines 449-465).
  • reqwest-enum/src/target.rs
    • Imported Error from crate root (line 2).
    • Removed timeout method from the Target trait (line 12).
    • Changed base_url, query, and headers method signatures to return String and HashMap<String, String> respectively (lines 8, 11, 12).
    • Changed body method signature to return Result<HTTPBody, Error> (line 14).
    • Updated query_string to collect into Vec<String> (line 21).
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds middleware support via reqwest-middleware, centralizes error handling, and refactors request building and target definitions.

  • Updated Target trait to use owned String types and return a fallible body()
  • Introduced a unified Error enum and conditional middleware client in Provider
  • Refactored request building to support timeouts, custom authentication, and JSON-RPC batch error mapping

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
reqwest-enum/src/target.rs Changed trait signatures to owned types and fallible bodies
reqwest-enum/src/provider.rs Integrated middleware client, added timeout handling, refactored builder
reqwest-enum/src/http.rs Made HTTPBody constructors return Result, extended AuthMethod
reqwest-enum/src/error.rs Added Error enum for unified error conversion
reqwest-enum/src/lib.rs Exposed new error module
reqwest-enum/src/jsonrpc.rs Mapped crate::Error to JsonRpcError
reqwest-enum/Cargo.toml Added middleware feature, bumped dependencies
examples/ethereum-rpc/src/ethereum_rpc.rs Updated example to new Target and error signatures
Cargo.toml Bumped workspace version and edition
Comments suppressed due to low confidence (2)

reqwest-enum/src/provider.rs:163

  • Calling send() on the RequestBuilder bypasses the middleware client in batch operations. Instead, build the Request and use self.client.execute(...) so that middleware layers are applied to batch requests as well.
let response = request.send().await?;

reqwest-enum/src/http.rs:92

  • Debug printing the password exposes sensitive credentials in logs. Consider masking or omitting the password field in the Debug implementation.
AuthMethod::Basic(username, password) => f.debug_tuple("Basic").field(username).field(password).finish(),

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces middleware support to reqwest-enum, a significant enhancement that also brings along improved error handling and API flexibility. Key changes include the integration of reqwest-middleware, a new Error enum, and updates to the Target trait and Provider implementation.

The introduction of AuthMethod::Custom and Provider::with_client are excellent additions for extensibility. The move towards String types for various parameters and Result for fallible operations generally improves robustness.

However, there are a few points, including some breaking changes and a potentially premature Rust edition update, that warrant discussion and consideration.

Summary of Findings

  • Rust Edition Update: The workspace is updated to Rust Edition 2024, which is not yet stable. This could impact users on stable toolchains.
  • Error Handling in From Implementation: A From<JsonRpcRequest> for reqwest::Body implementation uses .unwrap(), which could panic. Consider a fallible conversion for library code.
  • Temporary Client Creation: A temporary reqwest::Client is created in request_builder on each call. This is likely a workaround for middleware integration but worth confirming if it's optimal.
  • Removal of Target::timeout(): The timeout() method was removed from the Target trait, centralizing timeout logic to the Provider or requiring manual handling via request_fn for per-request timeouts. This impacts flexibility.
  • Breaking Changes: The PR includes several breaking changes to the Target trait and other public APIs, which is expected for a 0.x.0 version bump introducing new features but should be clearly communicated to users.

Merge Readiness

This pull request introduces valuable middleware support and other improvements. However, before merging, I recommend addressing the concern about the Rust Edition 2024 update, as it could be a blocker for users on stable toolchains. The medium-severity points regarding Target::timeout() removal, unwrap() usage, and temp_client creation should also be considered for potential refinement or clarification.

I am unable to approve pull requests directly. Please ensure these points are discussed and, if necessary, addressed, and that other reviewers provide their approval before merging.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🔭 Outside diff range comments (3)
reqwest-enum/src/provider.rs (3)

147-162: ⚠️ Potential issue

Fix request builder handling in batch_chunk_by.

Similar issues to the batch method with Result wrapping:

 let target = &chunk[0];
-let mut request = self.request_builder(target);
+let mut request = self.request_builder(target)?;
 let mut requests = Vec::<JsonRpcRequest>::new();
 for (k, v) in chunk.iter().enumerate() {
     let request = JsonRpcRequest::new(
         v.method_name(),
         v.params(),
         (chunk_idx * chunk_size + k + 1) as u64,
     );
     requests.push(request);
 }

 let http_body = HTTPBody::from_array(&requests).map_err(|e| JsonRpcError { code: -32700, message: format!("Failed to serialize batch chunk: {}", e) })?;
-request = Ok(request?.body(http_body.inner));
-rpc_requests.push(request?);
+request = request.body(http_body.inner);
+rpc_requests.push(request);

163-168: ⚠️ Potential issue

Use self.client for request execution to support middleware.

The current implementation uses RequestBuilder::send() which bypasses the configured client and any middleware.

Refactor to build requests and execute them through self.client:

-let bodies = join_all(rpc_requests.into_iter().map(|request| async move {
-    let response = request.send().await?;
-    let body = response.json::<Vec<JsonRpcResult<U>>>().await?;
-    Ok(body)
-}))
+let bodies = join_all(rpc_requests.into_iter().map(|request_builder| {
+    let client = self.client.clone();
+    async move {
+        let request = request_builder.build()?;
+        let response = client.execute(request).await?;
+        let body = response.json::<Vec<JsonRpcResult<U>>>().await?;
+        Ok::<Vec<JsonRpcResult<U>>, crate::Error>(body)
+    }
+}))

This ensures middleware and client configuration are properly applied.


169-186: 🛠️ Refactor suggestion

Improve error handling to preserve all chunk errors.

The current implementation only returns the last error if multiple chunks fail, losing valuable debugging information.

Consider collecting all errors or returning the first error:

 let mut results = Vec::<JsonRpcResult<U>>::new();
-let mut error: Option<JsonRpcError> = None;
+let mut errors = Vec::<JsonRpcError>::new();

 for result in bodies {
     match result {
         Ok(body) => {
             results.extend(body);
         }
         Err(err) => {
-            error = Some(err);
+            errors.push(err.into());
         }
     }
 }
-if let Some(err) = error {
-    return Err(err);
+if !errors.is_empty() {
+    // Return first error with count of total errors
+    let mut first_err = errors.into_iter().next().unwrap();
+    if errors.len() > 1 {
+        first_err.message = format!("{} (and {} more errors)", first_err.message, errors.len() - 1);
+    }
+    return Err(first_err);
 }
 Ok(results)
🧹 Nitpick comments (1)
reqwest-enum/src/jsonrpc.rs (1)

60-78: LGTM with suggestion for error code specificity

The error conversion implementation correctly handles the different error variants from the unified Error enum. The delegation to existing From<reqwest::Error> for JsonRpcError is appropriate, and the conditional compilation for middleware errors is properly handled.

Consider using more specific JSON-RPC error codes:

  • -32700 for parse errors (when SerdeJson errors are parsing-related)
  • -32603 for internal errors (current usage is appropriate for middleware and general serialization errors)
 crate::Error::SerdeJson(e) => JsonRpcError {
-    code: -32603, // Internal error (could also be Parse error -32700 depending on context)
+    code: -32700, // Parse error - more appropriate for serialization errors
     message: format!("Serialization/deserialization error: {}", e),
 },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b55ea49 and 28ec618.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • Cargo.toml (1 hunks)
  • examples/ethereum-rpc/src/ethereum_rpc.rs (3 hunks)
  • reqwest-enum/Cargo.toml (1 hunks)
  • reqwest-enum/src/error.rs (1 hunks)
  • reqwest-enum/src/http.rs (1 hunks)
  • reqwest-enum/src/jsonrpc.rs (1 hunks)
  • reqwest-enum/src/lib.rs (1 hunks)
  • reqwest-enum/src/provider.rs (11 hunks)
  • reqwest-enum/src/target.rs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
reqwest-enum/src/target.rs (2)
examples/ethereum-rpc/src/ethereum_rpc.rs (7)
  • base_url (144-146)
  • method (148-150)
  • path (152-154)
  • query (156-158)
  • headers (160-164)
  • authentication (166-168)
  • body (170-175)
reqwest-enum/src/provider.rs (7)
  • base_url (338-340)
  • method (342-349)
  • path (351-362)
  • query (364-366)
  • headers (368-370)
  • authentication (372-381)
  • body (383-395)
reqwest-enum/src/provider.rs (3)
reqwest-enum/src/jsonrpc.rs (4)
  • from (24-26)
  • from (52-57)
  • from (61-77)
  • new (13-20)
reqwest-enum/src/http.rs (4)
  • from (44-55)
  • from (59-63)
  • from_array (65-69)
  • header_api_key (82-88)
reqwest-enum/src/target.rs (8)
  • body (14-14)
  • base_url (8-8)
  • path (10-10)
  • method (9-9)
  • query (11-11)
  • query (18-21)
  • headers (12-12)
  • authentication (13-13)
🔇 Additional comments (15)
Cargo.toml (1)

2-2: Version bump is appropriate.

The version bump from 0.3.3 to 0.4.0 correctly reflects the addition of middleware support as a significant new feature.

reqwest-enum/src/lib.rs (1)

1-2: Well-designed error handling infrastructure.

The addition of a centralized error module with public re-export follows Rust best practices and provides a clean API for unified error handling across the crate.

reqwest-enum/Cargo.toml (1)

17-17: Well-designed optional middleware feature.

The conditional dependency on reqwest-middleware through the middleware feature flag provides good flexibility for users who don't need middleware support.

reqwest-enum/src/error.rs (1)

1-15: Excellent error handling design.

The Error enum demonstrates excellent Rust error handling practices:

  • Uses thiserror for clean error trait derivation
  • Provides descriptive error messages with context
  • Enables automatic conversions with #[from] attributes
  • Conditionally compiles middleware errors only when the feature is enabled
  • Covers all major error sources (HTTP, middleware, serialization)

This creates a robust foundation for error propagation throughout the crate.

reqwest-enum/src/target.rs (3)

1-5: Clean import organization

The updated imports correctly include the new Error type and maintain clean organization with the http module imports.


8-14: Excellent API evolution towards owned data and error handling

The trait changes represent a well-thought-out evolution:

  • Owned String types provide greater flexibility for implementations
  • Fallible body() method enables proper error propagation
  • Consistent use of HashMap<String, String> for headers and query parameters

These changes align well with the broader crate refactor towards explicit error handling.


17-23: Helper method correctly adapted for owned strings

The query_string method properly handles the transition from Vec<&str> to Vec<String> in the collect operation, maintaining the same functionality with the new owned string types.

examples/ethereum-rpc/src/ethereum_rpc.rs (4)

1-9: Clean import reorganization

The import updates correctly reflect the new API structure, with explicit HTTPBody import and proper use of HashMap from std collections.


144-145: Correct adaptation to owned string API

The base_url method properly returns an owned String using .to_string(), aligning with the updated Target trait signature.


156-164: Proper implementation of owned string collections

Both query and headers methods correctly use HashMap<String, String> with owned strings. The header insertion properly converts both key and value to owned strings.


170-175: Excellent error handling integration

The body method correctly:

  • Returns Result<HTTPBody, reqwest_enum::Error>
  • Uses the ? operator for error propagation from HTTPBody::from(&req)?
  • Maintains the same logic while adding proper error handling

This demonstrates good integration with the new fallible API design.

reqwest-enum/src/http.rs (4)

59-69: Excellent transition to fallible serialization

The changes to make HTTPBody::from and from_array fallible are well-implemented:

  • Using Vec<u8> writer with serde_json::to_writer is efficient
  • Proper error propagation with the ? operator
  • Consistent Result<Self, serde_json::Error> return type

This eliminates the previous .unwrap() calls that could panic, providing better error handling.


74-79: Enhanced authentication flexibility

The AuthMethod updates provide excellent improvements:

  • Owned String types for Basic and Bearer variants offer greater flexibility
  • The new Custom variant with boxed closure enables arbitrary authentication logic
  • Optional password in Basic auth is a practical addition

The closure approach for Custom auth is powerful and allows for complex authentication scenarios.


81-89: Useful helper function for common use case

The header_api_key helper function provides a convenient way to create custom header-based authentication. The implementation correctly:

  • Uses move closure to capture the owned strings
  • Clones the values in the closure for repeated use
  • Returns the appropriate AuthMethod::Custom variant

This addresses a common authentication pattern while demonstrating the flexibility of the Custom variant.


91-103: Thoughtful Debug implementation for complex enum

The manual Debug implementation properly handles all variants:

  • Basic and Bearer variants show their actual values
  • Custom variant displays "<function>" placeholder, which is appropriate since closures can't be meaningfully debugged

This provides useful debugging information while handling the non-debuggable closure case gracefully.

Copy link

@coderabbitai coderabbitai bot left a 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 comments (1)
reqwest-enum/src/provider.rs (1)

164-182: ⚠️ Potential issue

Fix error handling inconsistency in batch chunking.

The error handling pattern is inconsistent and potentially problematic. Line 180-181 has redundant Result wrapping that could cause compilation issues.

Apply this diff to fix the error handling:

-            let http_body = HTTPBody::from_array(&requests).map_err(|e| JsonRpcError { code: -32700, message: format!("Failed to serialize batch chunk: {}", e) })?;
-            request = Ok(request?.body(http_body.inner));
-            rpc_requests.push(request?);
+            let http_body = HTTPBody::from_array(&requests).map_err(|e| JsonRpcError { code: -32700, message: format!("Failed to serialize batch chunk: {}", e) })?;
+            let request_builder = request?.body(http_body.inner);
+            rpc_requests.push(request_builder);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 090b94b and dd9580a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • Cargo.toml (2 hunks)
  • examples/ethereum-rpc/src/ethereum_rpc.rs (3 hunks)
  • reqwest-enum/Cargo.toml (1 hunks)
  • reqwest-enum/src/http.rs (2 hunks)
  • reqwest-enum/src/provider.rs (11 hunks)
  • reqwest-enum/src/target.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • Cargo.toml
  • reqwest-enum/Cargo.toml
  • reqwest-enum/src/target.rs
  • examples/ethereum-rpc/src/ethereum_rpc.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (12)
reqwest-enum/src/http.rs (4)

60-64: Excellent improvement making serialization fallible.

The change from panicking to returning Result<Self, serde_json::Error> is a significant improvement that allows callers to handle serialization errors gracefully rather than crashing the application.


66-70: Consistent error handling for array serialization.

Good consistency with the from method by making array serialization also fallible.


104-110: API key helper provides good convenience and security.

The header_api_key helper function is well-designed, providing a safe and convenient way to create custom authentication for API keys. The use of clone() ensures the closure can be called multiple times safely.


113-125: Excellent Debug implementation handling closures appropriately.

The manual Debug implementation correctly handles the function pointer by showing a placeholder, which is the appropriate approach since closures cannot be meaningfully debugged. This maintains debuggability while protecting against potential information disclosure.

reqwest-enum/src/provider.rs (8)

17-23: Good conditional compilation for middleware support.

The type aliases and conditional imports provide clean separation between middleware and non-middleware builds. This approach maintains API compatibility while adding optional functionality.


59-70: Excellent conditional client field design.

The conditional compilation for the client field properly handles the different client types based on feature flags. This ensures the right client type is used with appropriate middleware support.


88-91: Proper error handling in request execution.

The request method correctly builds the request with error propagation and executes it using the configured client. This addresses the previous concern about using temporary clients.


274-310: Excellent comprehensive request builder implementation.

The request_builder method now properly addresses the previous review concerns by:

  1. Using self.client instead of creating temporary clients
  2. Returning Result for proper error handling
  3. Systematically applying all request configuration (query, headers, auth, body, timeout)
  4. Supporting the new AuthMethod::Custom variant

This is a significant improvement over the previous implementation.


183-191: Good conditional error handling for middleware.

The conditional compilation for different error types based on middleware feature is well-implemented, ensuring proper error handling in both scenarios.


457-466: Test improvements with async and proper error handling.

The conversion to async tests using tokio::test and proper error handling with expect is a good improvement that aligns with the crate's async nature.


468-482: Good test coverage for custom authentication.

The new test for header API key authentication provides good coverage of the new AuthMethod::Custom functionality, verifying that custom headers are properly applied.


127-149:

Details

✅ Verification successful

Verify batch request construction logic.

The batch processing has been improved but needs verification of the request builder usage pattern.

Verify that using a single representative target for the entire batch request is correct:


🏁 Script executed:

#!/bin/bash
# Search for batch request implementations to understand the intended pattern
rg -A 15 "representative_target" --type rust

Length of output: 1579


🏁 Script executed:

#!/bin/bash
# Locate and display the definition of `request_builder` in the provider module
rg -A 10 "fn request_builder" -n reqwest-enum/src/provider.rs

Length of output: 586


Review Batch Request Builder Usage

The batch implementation uses the first target’s HTTP method, URL, query parameters, and headers to construct the reqwest::RequestBuilder. JSON-RPC batch calls must hit the same HTTP endpoint with identical configurations, so reusing one “representative” target is correct—provided that all targets share the same base URL, HTTP method, query params, and headers.

• Confirm that T::query() and T::headers() return the same values across all batch targets.
• If certain targets require unique query parameters or headers, you’ll need to merge or override them per request instead of using just targets[0].

No further code changes required here if your RPC targets are homogeneous in URL, method, query, and headers.

@hewigovens hewigovens merged commit 3d2cca5 into main Jun 7, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants