exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit a14ef50b776e583c5730ea7b0a514c04322c3ee0
parent 7d866a446d61d40781a6d5c00300032e71519f99
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Wed, 28 May 2025 14:05:34 +0200

fix refund error handling: distinguish when coin is not found from database errors

Diffstat:
Msrc/exchange/taler-exchange-httpd_refund.c | 50++++++++++++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c @@ -36,6 +36,12 @@ /** + * How often do we retry after soft database errors? + */ +#define MAX_RETRIES 3 + + +/** * Generate successful refund confirmation message. * * @param connection connection to the client @@ -222,6 +228,7 @@ verify_and_execute_refund (struct MHD_Connection *connection, } /* Fetch the coin's denomination (hash) */ + for (unsigned int i = 0; i < MAX_RETRIES; i++) { enum GNUNET_DB_QueryStatus qs; @@ -229,21 +236,36 @@ verify_and_execute_refund (struct MHD_Connection *connection, &refund->coin.coin_pub, &rctx.known_coin_id, &refund->coin.denom_pub_hash); - if (0 > qs) + switch (qs) { - MHD_RESULT res; - char *dhs; - - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - dhs = GNUNET_STRINGS_data_to_string_alloc ( - &refund->coin.denom_pub_hash, - sizeof (refund->coin.denom_pub_hash)); - res = TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_REFUND_COIN_NOT_FOUND, - dhs); - GNUNET_free (dhs); - return res; + case GNUNET_DB_STATUS_SOFT_ERROR: + if (i < MAX_RETRIES - 1) + continue; + /* otherwise: fall-through */ + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "get_coin_denomination"); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + { + MHD_RESULT res; + char *dhs; + + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + dhs = GNUNET_STRINGS_data_to_string_alloc ( + &refund->coin.denom_pub_hash, + sizeof (refund->coin.denom_pub_hash)); + res = TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_EXCHANGE_REFUND_COIN_NOT_FOUND, + dhs); + GNUNET_free (dhs); + return res; + } + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; } }