From 51da1d44fd4f8e639989a7dfe80581abec2835e6 Mon Sep 17 00:00:00 2001 From: tudor-da Date: Tue, 23 Nov 2021 14:15:52 +0100 Subject: [PATCH] [Self-service error codes] Update existing error code references [DPP-593] (#11798) (#11821) * Updated Ledger API services protobuf definitions CHANGELOG_BEGIN CHANGELOG_END * Adapted Building Applications / Ledger API / gRPC section * Moved Error Codes under Building Applications / Ledger API / gRPC * Small rewording Error codes page * Updated outdated LedgerAPI / gRPC page * Apply suggestions from code review Co-authored-by: pbatko-da * Moved Error Codes under Building Applications / Ledger API / gRPC * Updated outdated LedgerAPI / gRPC page * Addressed review comments * Addressed review comments * Remove unnecessary link to error-codes * `Ledger API` changed to `Common Ledger API change` Co-authored-by: pbatko-da Co-authored-by: pbatko-da --- .../grpc/error-codes.rst} | 18 ++++----- docs/source/app-dev/grpc/index.rst | 32 +++++++++++---- docs/source/index.rst | 1 - docs/source/ops/index.rst | 2 +- .../v1/admin/config_management_service.proto | 3 ++ .../admin/participant_pruning_service.proto | 3 +- .../daml/ledger/api/v1/command_service.proto | 40 +++++++++++++------ .../api/v1/command_submission_service.proto | 9 +++-- .../ledger/api/v1/transaction_service.proto | 8 ++-- 9 files changed, 77 insertions(+), 39 deletions(-) rename docs/source/{error-codes/self-service/index.rst => app-dev/grpc/error-codes.rst} (99%) diff --git a/docs/source/error-codes/self-service/index.rst b/docs/source/app-dev/grpc/error-codes.rst similarity index 99% rename from docs/source/error-codes/self-service/index.rst rename to docs/source/app-dev/grpc/error-codes.rst index fb3c8cdf1374..38c2d548f888 100644 --- a/docs/source/error-codes/self-service/index.rst +++ b/docs/source/app-dev/grpc/error-codes.rst @@ -4,24 +4,21 @@ Error Codes ########### -.. toctree:: - :hidden: - Overview ********* .. _gRPC status codes: https://grpc.github.io/grpc/core/md_doc_statuscodes.html .. _gRPC status code: https://grpc.github.io/grpc/core/md_doc_statuscodes.html -.. _StatusRuntimeException: https://grpc.github.io/grpc-java/javadoc/io/grpc/StatusRuntimeException.html .. _rich gRPC error model: https://cloud.google.com/apis/design/errors#error_details .. _standard gRPC description: https://grpc.github.io/grpc-java/javadoc/io/grpc/Status.html#getDescription-- The majority of the errors are a result of some request processing. -They are logged and returned to the user as a failed gRPC request -using the standard StatusRuntimeException_. -As such this approach remains unchanged in principle while we aim at +They are logged and returned to the user as a failed gRPC response +containing the status code, an optional status message and optional metadata. + +This approach remains unchanged in principle while we aim at enhancing it by providing: - improved consistency of the returned errors across API endpoints, @@ -292,8 +289,7 @@ Anatomy of an Error --------------------------- -Errors returned to users are represented as instances of standard StatusRuntimeException_. -As such they contain a `gRPC status code`_, a description and additional machine readable information +Errors returned to users contain a `gRPC status code`_, a description and additional machine readable information represented in the `rich gRPC error model`_. @@ -369,8 +365,8 @@ compatibility with previous releases for some service Ledger API endpoints. The table below outlines all the cases and error conditions when a Ledger API service endpoint returns a different gRPC status code in comparison to the pre-1.18 releases. -Ledger API -^^^^^^^^^^ +Common Ledger API changes +^^^^^^^^^^^^^^^^^^^^^^^^^ The table below outlines generic gRPC status code changes pertaining to the Ledger API and apply to all ledger backends. For changes specific to a ledger backend, check the next subsections. diff --git a/docs/source/app-dev/grpc/index.rst b/docs/source/app-dev/grpc/index.rst index fa6235531c5a..5163e89bdee6 100644 --- a/docs/source/app-dev/grpc/index.rst +++ b/docs/source/app-dev/grpc/index.rst @@ -6,6 +6,12 @@ gRPC #### + +.. toctree:: + :hidden: + + error-codes + If you want to write an application for the ledger API in other languages, you'll need to use `gRPC `__ directly. If you're not familiar with gRPC and protobuf, we strongly recommend following the `gRPC quickstart `__ and `gRPC tutorials `__. This documentation is written assuming you already have an understanding of gRPC. @@ -66,19 +72,31 @@ For information on how Daml types and contracts are represented by the Ledger AP Error handling ************** -For the standard error codes that the server or the client might return, see the `gRPC documentation `__ . +The Ledger API generally uses the gRPC standard status codes for signaling response failures to client applications. -For submitted commands, there are these response codes: +For more details on the gRPC standard status codes, see the `gRPC documentation `__ . + +Generically, on submitted commands the Ledger API responds with the following gRPC status codes: ABORTED - The platform failed to record the result of the command due to a transient server-side error or a time constraint violation. You can retry the submission. In case of a time constraint violation, please refer to the section :ref:`Dealing with time ` on how to handle commands with long processing times. + The platform failed to record the result of the command due to a transient server-side error (e.g. backpressure due to high load) or a time constraint violation. You can retry the submission. In case of a time constraint violation, please refer to the section :ref:`Dealing with time ` on how to handle commands with long processing times. +DEADLINE_EXCEEDED (when returned by the Command Service) + The request might not have been processed, as its deadline expired before its completion was signalled. ALREADY_EXISTS - The command was rejected because it was sent within the deduplication period of a previous command with the same change ID. + The command was rejected because the resource (e.g. contract key) already exists or because it was sent within the deduplication period of a previous command with the same change ID. +NOT_FOUND + The command was rejected due to a missing resources (e.g. contract key not found). INVALID_ARGUMENT The submission failed because of a client error. The platform will definitely reject resubmissions of the same command. -OK, INTERNAL, UNKNOWN (when returned by the Command Submission Service) - Assume that the command was accepted, and wait for the resulting completion or a timeout from the Command Completion Service. +FAILED_PRECONDITION + The command was rejected due to an interpretation error or due to a consistency error due to races. +OK (when returned by the Command Submission Service) + Assume that the command was accepted and wait for the resulting completion or a timeout from the Command Completion Service. OK (when returned by the Command Service) You can be sure that the command was successful. INTERNAL, UNKNOWN (when returned by the Command Service) - Resubmit the command with the same command_id. + An internal system fault occurred. Contact the participant operator for the resolution. + +Aside from the standard gRPC status codes, the failures returned by the Ledger API are enriched with details meant to help the application +or the application developer to handle the error autonomously (e.g. by retrying on a retryable error). +For more details on the rich error details see the :doc:`error-codes` diff --git a/docs/source/index.rst b/docs/source/index.rst index c416512745c8..fca852cb5c5b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -52,7 +52,6 @@ Daml Documentation triggers/index tools/trigger-service/index tools/auth-middleware/index - error-codes/self-service/index .. toctree:: :titlesonly: diff --git a/docs/source/ops/index.rst b/docs/source/ops/index.rst index 17967c903af5..9ce2d9517837 100644 --- a/docs/source/ops/index.rst +++ b/docs/source/ops/index.rst @@ -40,7 +40,7 @@ How the Daml Ledger API is affected ----------------------------------- - Active data streams from the Daml Participant may abort and need to be re-established by the Daml application from a later offset than pruned, even if they are already streaming past it. -- Requesting information at offsets that predate pruning, including from the ledger's start, will result in a ``NOT_FOUND`` gRPC error. +- Requesting information at offsets that predate pruning, including from the ledger's start, will result in a ``FAILED_PRECONDITION`` gRPC error. - As a consequence, after pruning, a Daml application must bootstrap from the Active Contract Service and a recent offset [3]_. Submission validation and Daml Ledger API endpoints that write to the ledger are generally not affected by pruning; an exception is that in-progress calls could abort while awaiting completion. diff --git a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/config_management_service.proto b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/config_management_service.proto index 88acb0ba75e3..564e8bc1565a 100644 --- a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/config_management_service.proto +++ b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/config_management_service.proto @@ -12,6 +12,9 @@ option csharp_namespace = "Com.Daml.Ledger.Api.V1.Admin"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; +// Status: experimental interface, will change before it is deemed production +// ready +// // The ledger configuration management service provides methods for the ledger administrator // to change the current ledger configuration. The services provides methods to modify // different aspects of the configuration. diff --git a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/participant_pruning_service.proto b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/participant_pruning_service.proto index 39c8620d3be5..c0e1daff59ee 100644 --- a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/participant_pruning_service.proto +++ b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/admin/participant_pruning_service.proto @@ -25,7 +25,8 @@ service ParticipantPruningService { // - ``INTERNAL``: if the participant has encountered a failure and has potentially applied pruning partially. Such cases // warrant verifying the participant health before retrying the prune with the same (or a larger, valid) offset. // Successful retries after such errors ensure that different components reach a consistent pruning state. - // - ``FAILED_PRECONDITION``: if the participant is not able to prune at the specified offset. + // - ``FAILED_PRECONDITION``: if the participant is not yet able to prune at the specified offset. + // rpc Prune (PruneRequest) returns (PruneResponse); } diff --git a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_service.proto b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_service.proto index 9e407d112098..6c4132fb00d6 100644 --- a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_service.proto +++ b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_service.proto @@ -24,11 +24,15 @@ service CommandService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id + // - ``NOT_FOUND``: if the request does not include a valid ledger id or if a resource is missing (e.g. contract key) + // due to for example contention on resources + // - ``ALREADY_EXISTS`` if a resource is duplicated (e.g. contract key) // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields - // - ``RESOURCE_EXHAUSTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``ABORTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``FAILED_PRECONDITION``: on consistency errors (e.g. the contract key has changed since the submission) + // or if an interpretation error occurred // - ``UNAVAILABLE``: if the participant is not yet ready to submit commands or if the service has been shut down. - // - ``ABORTED``: if a contract key is missing or duplicated due to for example contention on resources + // - ``DEADLINE_EXCEEDED``: if the request failed to receive its completion within the predefined timeout. rpc SubmitAndWait (SubmitAndWaitRequest) returns (google.protobuf.Empty); // Submits a single composite command, waits for its result, and returns the transaction id. @@ -36,11 +40,15 @@ service CommandService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id + // - ``NOT_FOUND``: if the request does not include a valid ledger id or if a resource is missing (e.g. contract key) + // due to for example contention on resources + // - ``ALREADY_EXISTS`` if a resource is duplicated (e.g. contract key) // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields - // - ``RESOURCE_EXHAUSTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``ABORTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``FAILED_PRECONDITION``: on consistency errors (e.g. the contract key has changed since the submission) + // or if an interpretation error occurred // - ``UNAVAILABLE``: if the participant is not yet ready to submit commands or if the service has been shut down. - // - ``ABORTED``: if a contract key is missing or duplicated due to for example contention on resources + // - ``DEADLINE_EXCEEDED``: if the request failed to receive its completion within the predefined timeout. rpc SubmitAndWaitForTransactionId (SubmitAndWaitRequest) returns (SubmitAndWaitForTransactionIdResponse); // Submits a single composite command, waits for its result, and returns the transaction. @@ -48,11 +56,15 @@ service CommandService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id + // - ``NOT_FOUND``: if the request does not include a valid ledger id or if a resource is missing (e.g. contract key) + // due to for example contention on resources + // - ``ALREADY_EXISTS`` if a resource is duplicated (e.g. contract key) // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields - // - ``RESOURCE_EXHAUSTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``ABORTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``FAILED_PRECONDITION``: on consistency errors (e.g. the contract key has changed since the submission) + // or if an interpretation error occurred // - ``UNAVAILABLE``: if the participant is not yet ready to submit commands or if the service has been shut down. - // - ``ABORTED``: if a contract key is missing or duplicated due to for example contention on resources + // - ``DEADLINE_EXCEEDED``: if the request failed to receive its completion within the predefined timeout. rpc SubmitAndWaitForTransaction (SubmitAndWaitRequest) returns (SubmitAndWaitForTransactionResponse); // Submits a single composite command, waits for its result, and returns the transaction tree. @@ -60,11 +72,15 @@ service CommandService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id + // - ``NOT_FOUND``: if the request does not include a valid ledger id or if a resource is missing (e.g. contract key) + // due to for example contention on resources + // - ``ALREADY_EXISTS`` if a resource is duplicated (e.g. contract key) // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields - // - ``RESOURCE_EXHAUSTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``ABORTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``FAILED_PRECONDITION``: on consistency errors (e.g. the contract key has changed since the submission) + // or if an interpretation error occurred // - ``UNAVAILABLE``: if the participant is not yet ready to submit commands or if the service has been shut down. - // - ``ABORTED``: if a contract key is missing or duplicated due to for example contention on resources + // - ``DEADLINE_EXCEEDED``: if the request failed to receive its completion within the predefined timeout. rpc SubmitAndWaitForTransactionTree (SubmitAndWaitRequest) returns (SubmitAndWaitForTransactionTreeResponse); } diff --git a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_submission_service.proto b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_submission_service.proto index 202d4d63b7be..4f04a3a4b679 100644 --- a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_submission_service.proto +++ b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/command_submission_service.proto @@ -32,11 +32,14 @@ service CommandSubmissionService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id + // - ``NOT_FOUND``: if the request does not include a valid ledger id or if a resource is missing (e.g. contract key) + // due to for example contention on resources + // - ``ALREADY_EXISTS`` if a resource is duplicated (e.g. contract key) // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields + // - ``ABORTED``: if the number of in-flight commands reached the maximum (if a limit is configured) + // - ``FAILED_PRECONDITION``: on consistency errors (e.g. the contract key has changed since the submission) + // or if an interpretation error occurred // - ``UNAVAILABLE``: if the participant is not yet ready to submit commands or if the service has been shut down. - // - ``RESOURCE_EXHAUSTED``: if the participant or the ledger is overloaded. Clients should back off exponentially and retry. - // - ``ABORTED``: if a contract key is missing or duplicated due to for example contention on resources rpc Submit (SubmitRequest) returns (google.protobuf.Empty); } diff --git a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/transaction_service.proto b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/transaction_service.proto index 7885445f68d4..2fd77b308828 100644 --- a/ledger-api/grpc-definitions/com/daml/ledger/api/v1/transaction_service.proto +++ b/ledger-api/grpc-definitions/com/daml/ledger/api/v1/transaction_service.proto @@ -22,8 +22,9 @@ service TransactionService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id or if the ledger has been pruned before ``begin`` + // - ``NOT_FOUND``: if the request does not include a valid ledger id // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields (e.g. if ``before`` is not before ``end``) + // - ``FAILED_PRECONDITION``: if the ledger has been pruned after the subscription start offset // - ``OUT_OF_RANGE``: if the ``begin`` parameter value is not before the end of the ledger rpc GetTransactions (GetTransactionsRequest) returns (stream GetTransactionsResponse); @@ -32,8 +33,9 @@ service TransactionService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id or if the ledger has been pruned before ``begin`` + // - ``NOT_FOUND``: if the request does not include a valid ledger id // - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields (e.g. if ``before`` is not before ``end``) + // - ``FAILED_PRECONDITION``: if the ledger has been pruned after the subscription start offset // - ``OUT_OF_RANGE``: if the ``begin`` parameter value is not before the end of the ledger rpc GetTransactionTrees (GetTransactionsRequest) returns (stream GetTransactionTreesResponse); @@ -76,7 +78,7 @@ service TransactionService { // Errors: // - ``UNAUTHENTICATED``: if the request does not include a valid access token // - ``PERMISSION_DENIED``: if the claims in the token are insufficient to perform a given operation - // - ``NOT_FOUND``: if the request does not include a valid ledger id or no such transaction exists + // - ``NOT_FOUND``: if the request does not include a valid ledger id rpc GetLedgerEnd (GetLedgerEndRequest) returns (GetLedgerEndResponse); }