diff --git a/payjoin-cli/src/app/v1.rs b/payjoin-cli/src/app/v1.rs index d9a61506e..7dbbe9ac0 100644 --- a/payjoin-cli/src/app/v1.rs +++ b/payjoin-cli/src/app/v1.rs @@ -365,10 +365,7 @@ impl App { .commit_outputs(); let provisional_payjoin = try_contributing_inputs(payjoin.clone(), &bitcoind) - .unwrap_or_else(|e| { - log::warn!("Failed to contribute inputs: {}", e); - payjoin.commit_inputs() - }); + .map_err(ReplyableError::Implementation)?; let payjoin_proposal = provisional_payjoin.finalize_proposal( |psbt: &Psbt| { @@ -386,20 +383,19 @@ impl App { fn try_contributing_inputs( payjoin: payjoin::receive::v1::WantsInputs, bitcoind: &bitcoincore_rpc::Client, -) -> Result { +) -> Result { let candidate_inputs = bitcoind .list_unspent(None, None, None, None, None) - .context("Failed to list unspent from bitcoind")? + .map_err(ImplementationError::from)? .into_iter() .map(input_pair_from_list_unspent); - let selected_input = payjoin - .try_preserving_privacy(candidate_inputs) - .map_err(|e| anyhow!("Failed to make privacy preserving selection: {}", e))?; - log::debug!("selected input: {:#?}", selected_input); + + let selected_input = + payjoin.try_preserving_privacy(candidate_inputs).map_err(ImplementationError::from)?; Ok(payjoin .contribute_inputs(vec![selected_input]) - .expect("This shouldn't happen. Failed to contribute inputs.") + .map_err(ImplementationError::from)? .commit_inputs()) } diff --git a/payjoin-cli/src/app/v2.rs b/payjoin-cli/src/app/v2.rs index b091b0da4..27a951f1e 100644 --- a/payjoin-cli/src/app/v2.rs +++ b/payjoin-cli/src/app/v2.rs @@ -304,10 +304,7 @@ impl App { .commit_outputs(); let provisional_payjoin = try_contributing_inputs(payjoin.clone(), &bitcoind) - .unwrap_or_else(|e| { - log::warn!("Failed to contribute inputs: {}", e); - payjoin.commit_inputs() - }); + .map_err(ReplyableError::Implementation)?; let payjoin_proposal = provisional_payjoin.finalize_proposal( |psbt: &Psbt| { @@ -355,20 +352,19 @@ async fn handle_recoverable_error( fn try_contributing_inputs( payjoin: payjoin::receive::v2::WantsInputs, bitcoind: &bitcoincore_rpc::Client, -) -> Result { +) -> Result { let candidate_inputs = bitcoind .list_unspent(None, None, None, None, None) - .context("Failed to list unspent from bitcoind")? + .map_err(ImplementationError::from)? .into_iter() .map(input_pair_from_list_unspent); - let selected_input = payjoin - .try_preserving_privacy(candidate_inputs) - .map_err(|e| anyhow!("Failed to make privacy preserving selection: {}", e))?; - log::debug!("selected input: {:#?}", selected_input); + + let selected_input = + payjoin.try_preserving_privacy(candidate_inputs).map_err(ImplementationError::from)?; Ok(payjoin .contribute_inputs(vec![selected_input]) - .expect("This shouldn't happen. Failed to contribute inputs.") + .map_err(ImplementationError::from)? .commit_inputs()) } diff --git a/payjoin/src/receive/error.rs b/payjoin/src/receive/error.rs index 2f67d3462..e68b2a619 100644 --- a/payjoin/src/receive/error.rs +++ b/payjoin/src/receive/error.rs @@ -337,6 +337,17 @@ impl fmt::Display for SelectionError { } } +impl error::Error for SelectionError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + use InternalSelectionError::*; + + match &self.0 { + Empty => None, + UnsupportedOutputLength => None, + NotFound => None, + } + } +} impl From for SelectionError { fn from(value: InternalSelectionError) -> Self { SelectionError(value) } } @@ -363,6 +374,14 @@ impl fmt::Display for InputContributionError { } } +impl error::Error for InputContributionError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match &self.0 { + InternalInputContributionError::ValueTooLow => None, + } + } +} + impl From for InputContributionError { fn from(value: InternalInputContributionError) -> Self { InputContributionError(value) } }