Conversation
Derive PartialEq on PersistedError, ApiError, InternalPersistedError, RequestError, and InternalRequestError. This follows the rule from payjoin#768 (which closed payjoin#645): only implement PartialEq where every inner error type also implements it. Tests can now assert errors directly instead of comparing .to_string(). The old string comparison masked a wrong expectation in the fatal_advance test: the impl produces ApiError::FatalWithState, not ApiError::Fatal. The integration test binds on the OriginalPayload variant because the receive Error hierarchy cannot implement PartialEq, since bitcoin's PsbtParseError and http::Error lack it.
caarloshenriq
left a comment
There was a problem hiding this comment.
Thanks for the contribution
Concept ACK c9630d1
It is worth confirming one point before the final ACK: the fatal_advance fix changes the expected result from ApiError::Fatal to ApiError::FatalWithState. This is explained as a latent bug that was masked by the comparison using .to_string() (since both variants likely display the same way, hiding the discrepancy). That reasoning makes sense, but the PR merely adjusts the test to match what the transition implementation currently produces; it does not verify whether FatalWithState is actually the intended behavior for this transition. Is it correct to propagate the ErrorState in this case, or should this scenario result in a simple Fatal error without state? If this is confirmed to be correct, I can proceed with the full ACK.
|
@caarloshenriq Good question, and yes, carrying ErrorState is correct here. fatal_advance is a fatal error that still advances to a next state, so the state is part of the design. Commit 461b714 changed this on purpose and also updated the callers to consume the state. The old test could not tell Fatal and FatalWithState apart because both print the same text, so the assertion was stale, not the code. |
Summary
#645 asked for
PartialEqon the error types so tests could compare errors directly. It was closed by #768, which addedPartialEqonly where every inner error type also implements it, and removed manual implementations that could never be fully correct. This PR completes that coverage and replaces the remaining.to_string()error comparisons in tests with real structural checks (the TODOs still referencing #645).Changes
payjoin/src/core/persist.rsPartialEqonPersistedError,ApiError, andInternalPersistedError.ErrorState: PartialEqbound toverify_sync/verify_asyncandassert_eq!the errors instead of comparing.to_string().fatal_advanceexpectedApiError::Fatal, but the transition impl produces ApiError::FatalWithState`. The expectation now matches actual behavior.payjoin/src/core/receive/v1/error.rsPartialEqonRequestErrorandInternalRequestError. Every inner error type implementsPartialEq, so this follows the rule established in#768.payjoin/tests/integration.rsmatchon theError::Protocol(ProtocolError::OriginalPayload(_))variant, per the maintainer guidance in#768. The top-level receiveErrorhierarchy cannot implementPartialEqbecause inner types such asbitcoin::psbt::PsbtParseErrorandhttp::Errordo not.Checklist
hygienic commits. The branch contains one commit that passes
cargo fmt --check,cargo clippy --all-targets --all-features -D warnings,RUSTDOCFLAGS="-D warnings" cargo doc, and the localtest suites.
Disclosure: co-authored by opencode