diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py index d86a8b89178d69e3b24214ce2caa7beddbb52420..3181685fd4688fe45872c1c706dd6460aecf346e 100644 --- a/src/_zkapauthorizer/controller.py +++ b/src/_zkapauthorizer/controller.py @@ -78,12 +78,14 @@ class Unpaid(Exception): """ +@attr.s(frozen=True) class UnrecognizedFailureReason(Exception): """ An attempt was made to redeem a voucher and the response contained an unknown reason. The redemption attempt may be automatically retried at some point. """ + response = attr.ib() @attr.s @@ -530,7 +532,7 @@ class RistrettoRedeemer(object): elif reason == u"unpaid": raise Unpaid(voucher) - raise UnrecognizedFailureReason() + raise UnrecognizedFailureReason(result) self._log.info( "Redeemed: {public_key} {proof} {count}", diff --git a/src/_zkapauthorizer/tests/test_controller.py b/src/_zkapauthorizer/tests/test_controller.py index 71c8f4d3bafbc98901df546f390e24b3344d4b26..f84bf0523ed8c51ee47aba8ba8397e3860aba97b 100644 --- a/src/_zkapauthorizer/tests/test_controller.py +++ b/src/_zkapauthorizer/tests/test_controller.py @@ -893,8 +893,9 @@ class RistrettoRedeemerTests(TestCase): ``RistrettoRedeemer.redeemWithCounter`` returns a ``Deferred`` that fails with ``UnrecognizedFailureReason``. """ + details = u"mysterious" num_tokens = counter + extra_tokens - issuer = UnsuccessfulRedemption(u"mysterious") + issuer = UnsuccessfulRedemption(details) treq = treq_for_loopback_ristretto(issuer) redeemer = RistrettoRedeemer(treq, NOWHERE) random_tokens = redeemer.random_tokens_for_voucher(voucher, counter, num_tokens) @@ -908,7 +909,14 @@ class RistrettoRedeemerTests(TestCase): failed( AfterPreprocessing( lambda f: f.value, - IsInstance(UnrecognizedFailureReason), + Equals( + UnrecognizedFailureReason( + { + u"success": False, + u"reason": details, + } + ) + ), ), ), )