Skip to content

Commit

Permalink
[Self-service error codes] Update existing error code references [DPP…
Browse files Browse the repository at this point in the history
…-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 <[email protected]>

* 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 <[email protected]>

Co-authored-by: pbatko-da <[email protected]>
  • Loading branch information
tudor-da and pbatko-da authored Nov 23, 2021
1 parent e29c90c commit 51da1d4
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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`_.


Expand Down Expand Up @@ -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.
Expand Down
32 changes: 25 additions & 7 deletions docs/source/app-dev/grpc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://grpc.io>`__ directly.

If you're not familiar with gRPC and protobuf, we strongly recommend following the `gRPC quickstart <https://grpc.io/docs/quickstart/>`__ and `gRPC tutorials <https://grpc.io/docs/tutorials/>`__. This documentation is written assuming you already have an understanding of gRPC.
Expand Down Expand Up @@ -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 <https://github.com/grpc/grpc/blob/600272c826b48420084c2ff76dfb0d34324ec296/doc/statuscodes.md>`__ .
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 <https://github.com/grpc/grpc/blob/600272c826b48420084c2ff76dfb0d34324ec296/doc/statuscodes.md>`__ .

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 <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 <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`
1 change: 0 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ Daml Documentation
triggers/index
tools/trigger-service/index
tools/auth-middleware/index
error-codes/self-service/index

.. toctree::
:titlesonly:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/ops/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,63 @@ 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.
// Propagates the gRPC error of failed submissions including Daml interpretation errors.
// 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.
// Propagates the gRPC error of failed submissions including Daml interpretation errors.
// 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.
// Propagates the gRPC error of failed submissions including Daml interpretation errors.
// 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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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);

}
Expand Down

0 comments on commit 51da1d4

Please sign in to comment.