commit a9f9a19cad38e459091d7bca512454191262323a
parent 68ec79de376eaee18bba592c5f3ba6bdee4052de
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 21 Oct 2025 13:07:17 +0200
document error respones more precisely, #10514
Diffstat:
| M | core/api-exchange.rst | | | 110 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 76 insertions(+), 34 deletions(-)
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
@@ -187,7 +187,7 @@ possibly by using HTTPS.
// digital cash issued by this exchange.
// @since protocol **v21**.
shopping_url?: string;
-
+
// Open banking gateway base URL where wallets can
// initiate wire transfers to withdraw
// digital cash from this exchange.
@@ -1719,45 +1719,72 @@ exchange.
response, so if the network goes down during the transaction or before the
client can commit the coins signature to disk, the coins are not lost.
:http:statuscode:`403 Forbidden`:
- A signature is invalid.
- This response comes with a standard `ErrorDetail` response.
+ A signature is invalid. This is usually the reserve signature.
+ This response comes with a standard `ErrorDetail` response with
+ a code of ``TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID``.
:http:statuscode:`404 Not found`:
- A denomination key or the reserve are not known to the exchange. If the
- denomination key is unknown, this suggests a bug in the wallet as the
- wallet should have used current denomination keys from ``/keys``.
- In this case, the response will be a `DenominationUnknownMessage`.
- If the reserve is unknown, the wallet should not report a hard error yet, but
- instead simply wait for up to a day, as the wire transaction might simply
- not yet have completed and might be known to the exchange in the near future.
- In this case, the wallet should repeat the exact same request later again
- using exactly the same blinded coins.
- :http:statuscode:`409 Conflict`:
One of the following reasons occured:
- 1. The balance of the reserve is not sufficient to withdraw the coins of the
- indicated denominations. The response is `WithdrawError` object.
-
- 2. The reserve has a birthday set and requires the request to provide a ``max_age``
- value.
- The response comes with a standard `ErrorDetail` response with error-code
- ``TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED``
- and an additional field ``maximum_allowed_age`` for the maximum age (in years)
- that the client can commit to in a call to ``/withdraw``, this time
- with ``max_age`` set accordingly and ``coin_evs`` being an array
- of ``n*kappa`` elements of type `CoinEnvelope`.
+ 1. The reserve is unknown. The response comes with a standard
+ `ErrorDetail` response with error-code
+ ``TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN``.
+ If the reserve is unknown, the wallet should not report a
+ hard error, but instead long-poll for the reserve status to wait
+ for the wire transfer to complete.
+ Once the wire transfer has arrived,
+ the wallet should repeat the exact same request later again,
+ possibly using exactly the same blinded coins.
+ 2. A denomination keyis not known to the exchange.
+ The response comes with a standard
+ `ErrorDetail` response with error-code
+ ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN``.
+ This suggests the wallet has outdated ``/keys`` and
+ should fetch the latest ``/keys``.
+ :http:statuscode:`409 Conflict`:
+ One of the following reasons occured:
+ 1. The balance of the reserve is not sufficient to withdraw the
+ coins of the indicated denominations.
+ The response is `WithdrawError` object with an error code of
+ ``TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS``. An operation
+ withdrawing less money should succeed.
+ 2. The reserve has a birthday set and requires the request to
+ provide a ``max_age`` value.
+ The response comes with a standard `ErrorDetail` response with
+ an error-code of
+ ``TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED``
+ and an additional field ``maximum_allowed_age`` for the
+ maximum age (in years)
+ that the client can commit to in a call to ``/withdraw``, this time
+ with ``max_age`` set accordingly and ``coin_evs`` being an array
+ of ``n*kappa`` elements of type `CoinEnvelope`.
3. the provided value for ``max_age`` is higher than the allowed value
- according to the reserve's birthday. The response comes with a standard
- `ErrorDetail` response with error-code
- ``TALER_EC_EXCHANGE_AGE_WITHDRAW_MAXIMUM_AGE_TOO_LARGE``
- and an additional field ``maximum_allowed_age`` for the maximum age (in years)
- that the client can commit to in a call to ``/withdraw``
+ according to the reserve's birthday. The response comes with a
+ standard `ErrorDetail` response with error-code
+ ``TALER_EC_EXCHANGE_AGE_WITHDRAW_MAXIMUM_AGE_TOO_LARGE``
+ and an additional field ``maximum_allowed_age`` for the maximum
+ age (in years) that the client can commit to in a call
+ to ``/withdraw``.
:http:statuscode:`410 Gone`:
- A requested denomination key is not yet or no longer valid.
- It either before the validity start, past the expiration or was revoked.
- The response is a `DenominationGoneMessage`. Clients must evaluate the
- error code provided to understand which of the cases this is and handle it
- accordingly.
+ A requested denomination key is no longer valid. There are two cases:
+
+ 1. The denomination key is past its expiration.
+ The response is a `DenominationGoneMessage` with a code of
+ ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED``.
+ 2. The denominatoin key was revoked. The response is a
+ plain `ErrorDetail` with a code of
+ ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED``.
+ :http:statuscode:`412 Precondition Failed`:
+ A requested denomination key is not yet valid.
+ It is before the validity start time.
+ The response is a `DenominationGoneMessage` with
+ ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE``.
+ A common case might be a difference in the current time between
+ wallet and exchange. The wallet could probably just wait a bit and
+ retry. Checking the server's ``Date:`` header should allow the
+ wallet to figure out how long to wait. Alternatively, the wallet
+ could try with an the previous denomination key generation.
+ Note: this is a bit of an abuse of the HTTP status code.
:http:statuscode:`451 Unavailable for Legal Reasons`:
This reserve has received funds from a purse or the amount withdrawn
exceeds another legal threshold and thus the reserve must
@@ -1778,6 +1805,21 @@ exchange.
on the case.
:http:statuscode:`501 Not implemented`:
The client has provided a cipher that is not supported.
+ :http:statuscode:`502 Bad gateway`:
+ This indicates the exchange could not communicate with an
+ external process. This usually means the exchange could
+ not talk to one of its secmod helpers.
+ Here, a standard error message with a code of
+ ``TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE``
+ is returned.
+ Wallets should retry the requests (with some delays) at
+ a later time.
+ :http:statuscode:`503 Service Unavailable`:
+ This primarily happens when the exchange currently has no
+ denomination signing keys at all, for example because the
+ offline signature did not yet happen. In this case, a standard
+ error message with a code of
+ ``TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING`` is returned.
**Details:**