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:
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;
}
}