-
Notifications
You must be signed in to change notification settings - Fork 43
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
Only derive JsonError for errors that can return Json #526
base: master
Are you sure you want to change the base?
Conversation
553a644
to
be89d64
Compare
Pull Request Test Coverage Report for Build 13208094848Details
💛 - Coveralls |
b09d837
to
fd5274f
Compare
My refactor separates replyable from unreplyable errors. The biggest hurdle I've run into is when the payload gets parsed as a string before |
bd9620e
to
758b9cd
Compare
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.
What do you think about naming the variants RecoverableError
/UnrecoverableError
instead of Un/Replyable
? My brain keeps auto-correcting that to "replayable".
url::form_urlencoded::parse(query.as_bytes()), | ||
SUPPORTED_VERSIONS, | ||
) | ||
.map_err(InternalPayloadError::SenderParams)?; |
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.
on line 182 before this change, there is a log::debug!
that is now duplicated in validate_payload
.
payjoin-cli/src/app/v1.rs
Outdated
@@ -16,7 +16,7 @@ use hyper_util::rt::TokioIo; | |||
use payjoin::bitcoin::psbt::Psbt; | |||
use payjoin::bitcoin::{self, FeeRate}; | |||
use payjoin::receive::v1::{PayjoinProposal, UncheckedProposal}; | |||
use payjoin::receive::Error; | |||
use payjoin::receive::ReplyableError; |
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.
For brevity I prefer importing ReplyableError::{V1, Implementation}
and using the variants directly (like it's done in app/v2.rs
).
The abstraction simplifies and categorizes error handling
I've changed the design again. This time, Error is dividend into non_exhaustive Recoverable and V2 variants. I note that I do still prefer I removed the I'm not sure if it makes sense for the v1 module to return @spacebear21 please let me know what you think. I do indeed believe this is much closer to a stable reality based on actual hierarchy than it was before, especially since the fundamental difference between errors that may be returned to the sender is separated. |
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.
I'm ok with ReturnToSender
or maybe Returnable
.
I'm not sure if it makes sense for the v1 module to return RecoverableError
I'm not sure exactly where you mean - in extract_proposal_from_v1
? I'm fine with returning the lowest common denominator (RecoverableError) in v1 functions and letting callers map to Error
if needed.
On another note, I wonder if we should box a ImplementationError = Box<dyn Error + Send + Sync>
type so that the receiver function signatures can be more semantically correct:
e.g.
pub fn identify_receiver_outputs(
self,
is_receiver_output: impl Fn(&Script) -> Result<bool, ImplementationError>,
) -> Result<WantsOutputs, RecoverableError> {
payjoin/src/receive/error.rs
Outdated
#[cfg(feature = "v1")] | ||
use crate::receive::v1; |
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.
This looks like it could be removed too in favor of:
#[cfg(feature = "v1")]
V1(crate::receive::v1::RequestError),
Regarding names, I took a happy medium keeping ReplyableError but using the ReplyToSender variant. Re:
This is an incredible idea! I was playing around with returning Box from these functions yesterday but didn't quite discover that an alias is how to make this semantically correct. Added it as a third commit and it looks great, way easier to implement the receive state machine properly by using Now I'm wondering how to handle the straggling receive errors: SelectionError, OutputSubstitutionError, InputContributionError. If unrecoverable, they're probably all ReplyableError variants with an |
Only some errors are actually recoverable and must return JSON. Fix payjoin#522.
It's more semantically correct to show that closures return a Boxed error than expecting a specific variant of ReplyableError
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.
ACK 1358c50
Now I'm wondering how to handle the straggling receive errors: SelectionError, OutputSubstitutionError, InputContributionError. If unrecoverable, they're probably all ReplyableError variants with an unavailable or not enough money error code. I think I know how to address it in a follow up.
I think these are all technically recoverable from the receiver side, e.g. "try again with a different input selection". If the receiver can't handle them then they become unavailable in most (all?) cases. I'm not sure we should use the not-enough-money
error code for InternalInputContributionError::ValueTooLow
because BIP78 says it specifically applies to "could not bump the fee of the payjoin proposal. "
receive::v2::SessionError
variants are not recoverable and must not return JSON #522.Re: #403