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

Use walleterror for error handling in try_get_internal_address #460

Merged
merged 1 commit into from
Apr 3, 2024

Conversation

reez
Copy link
Collaborator

@reez reez commented Feb 26, 2024

I've just been looking thru what functions we currently use (or I use in a sample iOS project) that have Alpha3Error so I can turn those into more specific errors.

Description

Adds PersistenceError and replaces the use of Alpha3Error with PersistenceError in the try_get_internal_address function.

I added a unit test for PersistenceError as well.

Notes to the reviewers

Changelog notice

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

@reez reez changed the title Use walleterror for error handling in try_get_inter… Use walleterror for error handling in try_get_internal_address Feb 26, 2024
@reez reez force-pushed the reez/err-address branch 2 times, most recently from e503d3b to c644409 Compare February 27, 2024 15:06
@reez reez marked this pull request as ready for review February 28, 2024 20:15
Copy link

coderabbitai bot commented Feb 28, 2024

Warning

Rate Limit Exceeded

@reez has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 22 minutes and 38 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.
Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
Please see our FAQ for further information.

Commits Files that changed from the base of the PR and between 9a996b1 and c6d17b7.

Walkthrough

The recent updates aim to enhance error handling within the Bitcoin Dev Kit (BDK) FFI interface. Changes include renaming WalletCreationError to PersistBackendError, refining error structures via WalletError and PersistBackendError interfaces, and improving error handling consistency in wallet operations and persistence. The updates also introduce thorough testing to ensure robust error management.

Changes

Files Change Summaries
bdk-ffi/src/.../bdk.udl - Renamed WalletCreationError to PersistBackendError
- Updated WalletError and Wallet interfaces
- Added methods to PersistBackendError
bdk-ffi/src/error.rs - Renamed and reorganized WalletError
- Added PersistBackendError enum
- Updated error handling and added tests
bdk-ffi/src/lib.rs - Updated import from WalletCreationError to WalletError
bdk-ffi/src/wallet.rs - Updated error types and handling in Wallet struct methods

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?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

Note: Auto-reply has been disabled for this repository by the repository owner. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 generate unit testing code for this file.
    • @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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

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 as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration 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/coderabbit-overrides.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

@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.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 43c1ca6 and c644409.
Files selected for processing (4)
  • bdk-ffi/src/bdk.udl (2 hunks)
  • bdk-ffi/src/error.rs (5 hunks)
  • bdk-ffi/src/lib.rs (1 hunks)
  • bdk-ffi/src/wallet.rs (3 hunks)
Additional comments: 7
bdk-ffi/src/lib.rs (1)
  • 35-35: The change from WalletCreationError to WalletError aligns with the PR's objectives to enhance error handling by making it more generic. Ensure that all references to the old WalletCreationError have been updated to WalletError across the entire codebase.
Verification successful

The script's execution did not find any references to WalletCreationError, indicating that the replacement with WalletError has been successfully carried out across the Rust files in the codebase. This aligns with the PR's objectives to enhance error handling by making it more generic. However, it's important to ensure that WalletError is correctly implemented and used wherever WalletCreationError was previously referenced.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for any remaining references to WalletCreationError. Expecting no results.
rg --type rust 'WalletCreationError'

Length of output: 36

bdk-ffi/src/bdk.udl (2)
  • 19-19: Renaming WalletCreationError to WalletError in the UDL file is consistent with the PR's objectives. This change enhances the clarity and specificity of error handling.
  • 101-101: Updating the Throws annotation from WalletCreationError to WalletError in the Wallet interface aligns with the renaming and improves error specificity. Ensure all references and annotations have been correctly updated throughout the UDL file.

Also applies to: 106-106

Verification successful

The absence of output from the rg command searching for WalletCreationError suggests that there are no remaining references to WalletCreationError in the UDL file or anywhere else in the codebase. This aligns with the intended update of changing references from WalletCreationError to WalletError as mentioned in the review comment. Therefore, it can be concluded that the update has been correctly implemented throughout the UDL file.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that there are no remaining references to WalletCreationError in the UDL file.
rg --type udl 'WalletCreationError'

Length of output: 63



Script:

#!/bin/bash
# Verify that there are no remaining references to WalletCreationError in the UDL file.
rg 'WalletCreationError'

Length of output: 24

bdk-ffi/src/error.rs (1)
  • 32-32: Renaming WalletCreationError to WalletError and updating its variants and implementations in the error.rs file aligns with the PR's objectives to enhance error handling. This change makes error handling more specific and meaningful.
bdk-ffi/src/wallet.rs (3)
  • 35-35: The Wallet::new function now returns a Result<Self, WalletError>, aligning with the PR's objective to make error handling more specific to wallet operations. This change is appropriate and enhances the clarity of error handling in wallet creation.
  • 70-74: The try_get_internal_address method has been updated to return Result<AddressInfo, WalletError> instead of using Alpha3Error, and the error mapping now uses WalletError::Write. This change makes the error more specific and meaningful, aligning with the PR's objectives. However, ensure that WalletError::Write accurately represents all possible error conditions that could occur in this context.
  • 70-74: The change from Alpha3Error to WalletError in the try_get_internal_address method is a significant improvement in making the error handling more specific and meaningful. However, it's crucial to ensure that the WalletError::Write variant is the most appropriate choice for all possible errors that could occur in this method. Consider if there are other WalletError variants that might more accurately describe certain error conditions.

bdk-ffi/src/wallet.rs Outdated Show resolved Hide resolved
bdk-ffi/src/error.rs Outdated Show resolved Hide resolved
@reez reez self-assigned this Mar 6, 2024
@reez reez force-pushed the reez/err-address branch from c644409 to 2cde0e3 Compare March 6, 2024 16:49
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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b249dae and 2cde0e3.
Files selected for processing (4)
  • bdk-ffi/src/bdk.udl (2 hunks)
  • bdk-ffi/src/error.rs (5 hunks)
  • bdk-ffi/src/lib.rs (1 hunks)
  • bdk-ffi/src/wallet.rs (3 hunks)
Files skipped from review as they are similar to previous changes (4)
  • bdk-ffi/src/bdk.udl
  • bdk-ffi/src/error.rs
  • bdk-ffi/src/lib.rs
  • bdk-ffi/src/wallet.rs

@reez reez requested a review from thunderbiscuit March 6, 2024 17:38
@thunderbiscuit
Copy link
Member

thunderbiscuit commented Mar 19, 2024

Those pesky errors. So now this remaps a write error from a PersistBackend::Write error to a NewOrLoadError::Write.

I'm worried about the confusion that we're about to introduce as Rust errors are attempted to be mapped to the ffi layer, but can't be fully mapped either (see my PR on persistence) because some of the methods change or combine multiple Rust calls and must therefore combine the potentially returned errors.

Sorry I'm just venting here. But errors are a big mess right now, and we haven't even begun to seriously get into them.

@reez
Copy link
Collaborator Author

reez commented Mar 19, 2024

Those pesky errors. So now this remaps a write error from a PersistBackend::Write error to a NewOrLoadError::Write.

I'm worried about the confusion that we're about to introduce as Rust errors are attempted to be mapped to the ffi layer, but can't be fully mapped either (see my PR on persistence) because some of the methods change or combine multiple Rust calls and must therefore combine the potentially returned errors.

Sorry I'm just venting here. But errors are a big mess right now, and we haven't even begun to seriously get into them.

I totally understand what youre saying, and those concerns about the complexities here error mapping from Rust to the FFI layer and also the potential for confusion this might introduce. Error handling across FFI boundaries definitely has some challenges, especially as we try to maintain clarity and meaningfulness in the errors presented at the FFI layer while trying to encapsulate the richness+specificity of Rust's error handling.

Hopefully this PR is a way for us to inch forward towards how all of this is going to work out since that's the general direction we are heading towards, that's why I tried to keep it as small+tight as possible without doing much refactoring and kind of naming+leaving these things in plain sight that "stick out like a sore thumb" at the moment.

@thunderbiscuit thunderbiscuit force-pushed the reez/err-address branch 3 times, most recently from bac73b7 to f2d4545 Compare March 20, 2024 16:43
@thunderbiscuit
Copy link
Member

thunderbiscuit commented Mar 20, 2024

I'm playing with the thiserror library to see if we can make these errors a little easier to work with. thiserror is a very common library in the Rust ecosystem, and provides I think a good way to simplify our code and make it easier to maintain. It's also one of the recommended libraries in the uniffi documentation. I added 2 commits to this PR to demonstrate a little bit how it might work.

@reez @notmandatory let me know what you think. If there is interest, I might actually go and attempt a refactor of our current set of errors using it as a separate PR.

Here is the gist of what it comes down to:

Before

#[derive(Debug)]
pub enum WalletError {
    // Errors coming from the FileError enum
    Io {
        e: String,
    },
    InvalidMagicBytes {
        got: Vec<u8>,
        expected: Vec<u8>,
    },

    // Errors coming from the NewOrLoadError enum
    Descriptor,
    Write,
    Load,
    NotInitialized,
    LoadedGenesisDoesNotMatch,
    LoadedNetworkDoesNotMatch {
        expected: Network,
        got: Option<Network>,
    },
}

impl fmt::Display for WalletError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Io { e } => write!(f, "io error trying to read file: {}", e),
            Self::InvalidMagicBytes { got, expected } => write!(
                f,
                "file has invalid magic bytes: expected={:?} got={:?}",
                expected, got,
            ),
            Self::Descriptor => write!(f, "error with descriptor"),
            Self::Write => write!(f, "failed to write to persistence"),
            Self::Load => write!(f, "failed to load from persistence"),
            Self::NotInitialized => {
                write!(f, "wallet is not initialized, persistence backend is empty")
            }
            Self::LoadedGenesisDoesNotMatch => {
                write!(f, "loaded genesis hash does not match the expected one")
            }
            Self::LoadedNetworkDoesNotMatch { expected, got } => {
                write!(f, "loaded network type is not {}, got {:?}", expected, got)
            }
        }
    }
}

impl std::error::Error for WalletError {}

thiserror

#[derive(Debug, thiserror::Error)]
pub enum WalletError {
    #[error("IO error, this may mean that the file is too short")]
    Io,

    #[error("file has invalid magic bytes: expected={expected:?} got={got:?}")]
    InvalidMagicBytes { got: Vec<u8>, expected: Vec<u8> },

    #[error("error with descriptor")]
    Descriptor,

    #[error("failed to write to persistence")]
    Write,

    #[error("failed to load from persistence")]
    Load,

    #[error("wallet is not initialized, persistence backend is empty")]
    NotInitialized,

    #[error("loaded genesis hash does not match the expected one")]
    LoadedGenesisDoesNotMatch,

    #[error("loaded network type is not {expected}, got {got:?}")]
    LoadedNetworkDoesNotMatch { expected: Network, got: Option<Network> },
}

The From traits still need to be implemented for the Rust errors however, so that part doesn't really get benefits from using thiserror.

@reez
Copy link
Collaborator Author

reez commented Mar 25, 2024

Good work @thunderbiscuit

I think we should try thiserror out, the one thing I do want us to keep an eye on is the potential increase in compilation times due to the procedural macros of thiserror.

ACK f2d4545

@reez reez force-pushed the reez/err-address branch 2 times, most recently from f597fa4 to a265112 Compare April 2, 2024 16:43
@reez
Copy link
Collaborator Author

reez commented Apr 2, 2024

@thunderbiscuit I rebased this on master so I could get the newest thiserror changes and such. So the changes in this PR atm are:

  • replaces the use of Alpha3Error with WalletCreationError in the try_get_internal_address function.
  • added a unit test to test all cases of the WalletCreationError enum

Wanted to get your feedback on what your thoughts on how this should shape up before it is mergeable? I didn't rename WalletCreationError to WalletError anymore, but I'm still using WalletCreationError's WriteError even though that may still seem like a bit of an awkward thing, so just wanted to get your thoughts on where you think that Error return type for try_get_internal_address should be in your head.

@thunderbiscuit
Copy link
Member

thunderbiscuit commented Apr 2, 2024

After playing with it a bit, it felt to me like those were fairly distinct errors. I feel like this is initially hidden by the fact that they both use the persistence's WriteError (try_get_internal_address uses it outright, new_or_load more indirectly as a generic on its own enum error, NewOrLoadError). Fundamentally I think the errors are closer to this:

Which makes me want to reduce it to the following two distinct errors:

  • try_get_internal_address: PersistenceBackend::WriteError
  • new_or_load: NewOrLoadError::WriteError

Open to discussing more of course.

@reez reez force-pushed the reez/err-address branch 3 times, most recently from 1a07c41 to 47d0b10 Compare April 2, 2024 21:50
@reez reez force-pushed the reez/err-address branch from 47d0b10 to c6d17b7 Compare April 2, 2024 21:52
@reez
Copy link
Collaborator Author

reez commented Apr 3, 2024

After playing with it a bit, it felt to me like those were fairly distinct errors. I feel like this is initially hidden by the fact that they both use the persistence's WriteError (try_get_internal_address uses it outright, new_or_load more indirectly as a generic on its own enum error, NewOrLoadError). Fundamentally I think the errors are closer to this:

Which makes me want to reduce it to the following two distinct errors:

  • try_get_internal_address: PersistenceBackend::WriteError
  • new_or_load: NewOrLoadError::WriteError

Open to discussing more of course.

Pushed some updates to this per your comments and our convo, I think its ready to go, but let me know if any other thoughts/updates, happy to change anything else if needed-

Copy link
Member

@thunderbiscuit thunderbiscuit left a comment

Choose a reason for hiding this comment

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

ACK c6d17b7.

@thunderbiscuit thunderbiscuit merged commit c6d17b7 into bitcoindevkit:master Apr 3, 2024
17 checks passed
@reez reez deleted the reez/err-address branch April 3, 2024 14:04
@reez reez mentioned this pull request Apr 3, 2024
8 tasks
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