@@ -266,46 +266,38 @@ pub enum ResponseError {
266266}
267267
268268impl ResponseError {
269- fn from_json ( json : serde_json:: Value ) -> Self {
270- // we try to find the errorCode field and
271- // if it exists we try to parse it as a well known error
272- // if its an unknown error we return the error code and message
273- // from original response
274- // if errorCode field doesn't exist we return parse error
269+ pub ( crate ) fn from_json ( json : serde_json:: Value ) -> Self {
275270 let message = json
276271 . as_object ( )
277272 . and_then ( |v| v. get ( "message" ) )
278273 . and_then ( |v| v. as_str ( ) )
279274 . unwrap_or_default ( )
280275 . to_string ( ) ;
281- if let Some ( error_code) =
282- json. as_object ( ) . and_then ( |v| v. get ( "errorCode" ) ) . and_then ( |v| v. as_str ( ) )
283- {
284- match ErrorCode :: from_str ( error_code) {
276+
277+ let error_code = json. as_object ( ) . and_then ( |v| v. get ( "errorCode" ) ) . and_then ( |v| v. as_str ( ) ) ;
278+
279+ match error_code {
280+ Some ( code) => match ErrorCode :: from_str ( code) {
285281 Ok ( ErrorCode :: VersionUnsupported ) => {
286282 let supported = json
287283 . as_object ( )
288284 . and_then ( |v| v. get ( "supported" ) )
289285 . and_then ( |v| v. as_array ( ) )
290286 . map ( |array| array. iter ( ) . filter_map ( |v| v. as_u64 ( ) ) . collect :: < Vec < u64 > > ( ) )
291287 . unwrap_or_default ( ) ;
292- WellKnownError :: VersionUnsupported { message, supported } . into ( )
288+ WellKnownError :: version_unsupported ( message, supported) . into ( )
293289 }
294- Ok ( ErrorCode :: Unavailable ) => WellKnownError :: Unavailable ( message) . into ( ) ,
295- Ok ( ErrorCode :: NotEnoughMoney ) => WellKnownError :: NotEnoughMoney ( message) . into ( ) ,
296- Ok ( ErrorCode :: OriginalPsbtRejected ) =>
297- WellKnownError :: OriginalPsbtRejected ( message) . into ( ) ,
298- _ => Self :: Unrecognized { error_code : error_code. to_string ( ) , message } ,
299- }
300- } else {
301- InternalValidationError :: Parse . into ( )
290+ Ok ( code) => WellKnownError :: new ( code, message) . into ( ) ,
291+ Err ( _) => Self :: Unrecognized { error_code : code. to_string ( ) , message } ,
292+ } ,
293+ None => InternalValidationError :: Parse . into ( ) ,
302294 }
303295 }
304296
305297 /// Parse a response from the receiver.
306298 ///
307299 /// response must be valid JSON string.
308- pub fn parse ( response : & str ) -> Self {
300+ pub ( crate ) fn parse ( response : & str ) -> Self {
309301 match serde_json:: from_str ( response) {
310302 Ok ( json) => Self :: from_json ( json) ,
311303 Err ( _) => InternalValidationError :: Parse . into ( ) ,
@@ -346,8 +338,8 @@ impl fmt::Debug for ResponseError {
346338 match self {
347339 Self :: WellKnown ( e) => {
348340 let json = serde_json:: json!( {
349- "errorCode" : e. error_code ( ) . to_string( ) ,
350- "message" : e. message( )
341+ "errorCode" : e. code . to_string( ) ,
342+ "message" : e. message
351343 } ) ;
352344 write ! ( f, "Well known error: {}" , json)
353345 }
@@ -364,41 +356,39 @@ impl fmt::Debug for ResponseError {
364356 }
365357}
366358
359+ /// A well-known error that can be safely displayed to end users.
367360#[ derive( Debug , Clone , PartialEq , Eq ) ]
368- #[ non_exhaustive]
369- pub enum WellKnownError {
370- Unavailable ( String ) ,
371- NotEnoughMoney ( String ) ,
372- VersionUnsupported { message : String , supported : Vec < u64 > } ,
373- OriginalPsbtRejected ( String ) ,
361+ pub struct WellKnownError {
362+ pub ( crate ) code : ErrorCode ,
363+ pub ( crate ) message : String ,
364+ pub ( crate ) supported_versions : Option < Vec < u64 > > ,
374365}
375366
376367impl WellKnownError {
377- pub fn error_code ( & self ) -> ErrorCode {
378- match self {
379- WellKnownError :: Unavailable ( _) => ErrorCode :: Unavailable ,
380- WellKnownError :: NotEnoughMoney ( _) => ErrorCode :: NotEnoughMoney ,
381- WellKnownError :: VersionUnsupported { .. } => ErrorCode :: VersionUnsupported ,
382- WellKnownError :: OriginalPsbtRejected ( _) => ErrorCode :: OriginalPsbtRejected ,
383- }
368+ /// Create a new well-known error with the given code and message.
369+ pub ( crate ) fn new ( code : ErrorCode , message : String ) -> Self {
370+ Self { code, message, supported_versions : None }
384371 }
385- pub fn message ( & self ) -> & str {
386- match self {
387- WellKnownError :: Unavailable ( m) => m,
388- WellKnownError :: NotEnoughMoney ( m) => m,
389- WellKnownError :: VersionUnsupported { message : m, .. } => m,
390- WellKnownError :: OriginalPsbtRejected ( m) => m,
391- }
372+
373+ /// Create a version unsupported error with the given message and supported versions.
374+ pub ( crate ) fn version_unsupported ( message : String , supported : Vec < u64 > ) -> Self {
375+ Self { code : ErrorCode :: VersionUnsupported , message, supported_versions : Some ( supported) }
392376 }
393377}
394378
395- impl Display for WellKnownError {
396- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
397- match self {
398- Self :: Unavailable ( _) => write ! ( f, "The payjoin endpoint is not available for now." ) ,
399- Self :: NotEnoughMoney ( _) => write ! ( f, "The receiver added some inputs but could not bump the fee of the payjoin proposal." ) ,
400- Self :: VersionUnsupported { supported : v, .. } => write ! ( f, "This version of payjoin is not supported. Use version {:?}." , v) ,
401- Self :: OriginalPsbtRejected ( _) => write ! ( f, "The receiver rejected the original PSBT." ) ,
379+ impl core:: fmt:: Display for WellKnownError {
380+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
381+ match self . code {
382+ ErrorCode :: Unavailable => write ! ( f, "The payjoin endpoint is not available for now." ) ,
383+ ErrorCode :: NotEnoughMoney => write ! ( f, "The receiver added some inputs but could not bump the fee of the payjoin proposal." ) ,
384+ ErrorCode :: VersionUnsupported => {
385+ if let Some ( supported) = & self . supported_versions {
386+ write ! ( f, "This version of payjoin is not supported. Use version {:?}." , supported)
387+ } else {
388+ write ! ( f, "This version of payjoin is not supported." )
389+ }
390+ }
391+ ErrorCode :: OriginalPsbtRejected => write ! ( f, "The receiver rejected the original PSBT." ) ,
402392 }
403393 }
404394}
@@ -414,8 +404,8 @@ mod tests {
414404 let known_str_error = r#"{"errorCode":"version-unsupported", "message":"custom message here", "supported": [1, 2]}"# ;
415405 match ResponseError :: parse ( known_str_error) {
416406 ResponseError :: WellKnown ( e) => {
417- assert_eq ! ( e. error_code ( ) , ErrorCode :: VersionUnsupported ) ;
418- assert_eq ! ( e. message( ) , "custom message here" ) ;
407+ assert_eq ! ( e. code , ErrorCode :: VersionUnsupported ) ;
408+ assert_eq ! ( e. message, "custom message here" ) ;
419409 assert_eq ! (
420410 e. to_string( ) ,
421411 "This version of payjoin is not supported. Use version [1, 2]."
0 commit comments