-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADP-291: Document endpoints error codes in the API documentation #2258
Conversation
d2aee15
to
aa7650a
Compare
aa7650a
to
ff52b1f
Compare
ff52b1f
to
623af75
Compare
623af75
to
1203859
Compare
1203859
to
1ddd32b
Compare
errStr = case res of | ||
Error s -> s | ||
_ -> "" | ||
in counterexample errStr $ res == Success SchemaApiErrorCode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shows a nice error message:
Cardano.Wallet.Api.Types
Api Errors
Every constructor from ApiErrorCode has a corresponding type in the schema FAILED [1]
Failures:
test/unit/Cardano/Wallet/Api/TypesSpec.hs:937:9:
1) Cardano.Wallet.Api.Types, Api Errors, Every constructor from ApiErrorCode has a corresponding type in the schema
Falsifiable (after 1 test):
Missing ApiErrorCode constructors for: ["RejectedTip","InvalidDelegationDiscovery","NotImplemented","WalletNotResponding","AddressAlreadyExists","UtxoTooSmall","WithdrawalNotWorth","PastHorizon","UnableToAssignInputOutput"]
Each of these need a corresponding swagger type of the form: x-errConstructorName
To rerun use: --match "/Cardano.Wallet.Api.Types/Api Errors/Every constructor from ApiErrorCode has a corresponding type in the schema/"
Randomized with seed 1387792531
…n which they may occur. Also, I've re-organized a bit their declarations so that they are listed in the same order as the branches on their corresponding sum-type in Haskell, so it's easier to map from one to another.
c215dce
to
7225066
Compare
bors r+ |
2258: ADP-291: Document endpoints error codes in the API documentation r=hasufell a=hasufell # Issue Number ADP-291 # Implementation approach This is all best-effort. There are no static checks to ensure we didn't miss anything. There's ongoing work at servant to make this possible: haskell-servant/servant#841 But even that would require a major refactor. Testing all possible errors is also an option, but seems quite excessive. The workflow for figuring out the error codes is roughly: 1. follow the entry point to the the `Handler ()` function e.g. ```hs listTransactions :: forall ctx s t k n. (ctx ~ ApiLayer s t k) => ctx ... -> Handler [ApiTransaction n] ``` 2. check all `liftHandler` calls, which have functions with `ExceptT` as argument, e.g.: ```hs listTransactions :: forall ctx s k t. ( HasDBLayer s k ctx , HasNetworkLayer t ctx ) => ctx ... -> ExceptT ErrListTransactions IO [TransactionInfo] ``` 3. find all the LiftHandler instance, e.g. ```hs instance LiftHandler ErrListTransactions where handler = \case ErrListTransactionsNoSuchWallet e -> handler e ErrListTransactionsStartTimeLaterThanEndTime e -> handler e ErrListTransactionsMinWithdrawalWrong -> apiError err400 MinWithdrawalWrong "The minimum withdrawal value must be at least 1 Lovelace." ErrListTransactionsPastHorizonException e -> handler e ``` 4. follow the recursive handlers to resolve all errors and add client error types to `swagger.yaml`. The error code is the 3rd `ApiErrorCode` argument to `apiError`. 5. Some errors are implicit, e.g. failed parameter parsing etc. These are also in `ApiErrorCode`. Also see the special instance `instance LiftHandler (Request, ServerError)` 6. repeat until exhaustion # Overview - [x] Wallets - [x] Addresses - [x] Coin Selections - [x] Transactions - [x] Migrations - [x] Stake Pools - [x] Utils - [x] Network - [x] Proxy - [x] Settings - [ ] Byron-specific endpoints # Remarks 1. I did not double check the byron endpoints. Many of their endpoints share the same types in `swagger.yaml`, so I assumed they have the same behavior wrt error codes. 2. This will generally be hard to maintain, since yaml anchors aren't enough to express the overlaps of error codes and group them sensibly. It would need something like [dhall](https://github.com/dhall-lang/dhall-lang) to do that. 3. I removed 405 errors, because the HTTP method is part of the very spec. If you follow the spec, you can't get 405. <!-- Don't forget to: ✓ Self-review your changes to make sure nothing unexpected slipped through ✓ Assign yourself to the PR ✓ Assign one or several reviewer(s) ✓ Once created, link this PR to its corresponding ticket ✓ Assign the PR to a corresponding milestone ✓ Acknowledge any changes required to the Wiki --> Co-authored-by: Julian Ospald <julian.ospald@iohk.io> Co-authored-by: KtorZ <matthias.benkort@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work on documenting error messages. I've left few comments.
properties: | ||
message: | ||
type: string | ||
description: May occur when trying to forget a transaction that is not pending. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to note this will change after https://github.com/input-output-hk/cardano-wallet/pull/2262/files#diff-a2398827a22606930a9b4edc67dfc9c99196a94cdb56c56ef0ef5f92512d42e0R2467 merged. Also expired transaction will be "forgettable".
schema: | ||
oneOf: | ||
- <<: *errBadRequest | ||
- <<: *errTransactionIsTooBig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrSelectForPaymentTxTooLarge maxSize maxN ->
apiError err400 TransactionIsTooBig $ mconcat
[ "I am afraid that the transaction you're trying to submit is "
, "too large! The network allows transactions only as large as "
, pretty maxSize, "s! As it stands, the current transaction only "
, "allows me to select up to ", showT maxN, " inputs. Note "
, "that I am selecting inputs randomly, so retrying *may work* "
, "provided I end up choosing bigger inputs sufficient to cover "
, "the transaction cost. Alternatively, try sending to less "
, "recipients or with smaller metadata."
]
it is 400
content: | ||
application/json: | ||
schema: | ||
<<: *errNoSuchWallet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same 410
and errNoSuchWallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is 410
ErrSignPaymentNoSuchWallet e -> (handler e)
{ errHTTPCode = 410
, errReasonPhrase = errReasonPhrase err410
}
@@ -1908,19 +2401,12 @@ x-responsesErr404: &responsesErr404 | |||
application/json: | |||
schema: *responsesErr | |||
|
|||
x-responsesErr405: &responsesErr405 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we think it is irrelevant to highlight in API doc? Basically every endpoint may return this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. The spec includes which method to use. If you follow the spec, 405 will never be returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then 406
and 415
should be removed also I guess, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
415 maybe, but the swagger spec doesn't document enough for 406 to not be a concern afais.
content: | ||
application/json: | ||
schema: | ||
<<: *errNoSuchWallet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same 410
and errNoSuchWallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrSignPaymentNoSuchWallet e -> (handler e)
{ errHTTPCode = 410
, errReasonPhrase = errReasonPhrase err410
}
content: | ||
application/json: | ||
schema: | ||
<<: *errNoSuchWallet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR isn't really about refactoring or fixing our error codes though. I just added documentation to the existing error handlers. I changed nothing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK. It revealed those small inconsistencies though (I spotted 410 and 403 only).
Could be fixed in this go if it's not a lot of work, but don't have to of course.
content: | ||
application/json: | ||
schema: | ||
<<: *errNoSuchWallet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same 410
and errNoSuchWallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrSignPaymentNoSuchWallet e -> (handler e)
{ errHTTPCode = 410
, errReasonPhrase = errReasonPhrase err410
}
bors r- |
Canceled. |
bors r+ |
Build succeeded: |
2293: Revise API error codes r=piotr-iohk a=piotr-iohk # Issue Number ADP-291 # Overview - f533091 Revise error codes: - 404 when wallet not found - 403 when transaction is too big - 430a31f Update swagger - e90b264 Update integration tests # Comments Whie reviewing #2258 I noticed that some error codes are a bit inconsistent, e.g.: - 410 or 404 is returned when the wallet is not found. - 400 or 403 - when transaction is too big. This pr is about to revise it and: - return 404 on wallet not found (removing 410 altogether) - return 403 on transaction too big Co-authored-by: Piotr Stachyra <piotr.stachyra@iohk.io>
Issue Number
ADP-291
Implementation approach
This is all best-effort. There are no static checks to ensure we didn't miss anything. There's ongoing work at servant to make this possible: haskell-servant/servant#841
But even that would require a major refactor.
Testing all possible errors is also an option, but seems quite excessive.
The workflow for figuring out the error codes is roughly:
Handler ()
function e.g.liftHandler
calls, which have functions withExceptT
as argument, e.g.:swagger.yaml
. The error code is the 3rdApiErrorCode
argument toapiError
.ApiErrorCode
. Also see the special instanceinstance LiftHandler (Request, ServerError)
Overview
Remarks
swagger.yaml
, so I assumed they have the same behavior wrt error codes.