Skip to content
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

[Self-service error codes] Update existing error code references [DPP-593] #11798

Merged
merged 12 commits into from
Nov 22, 2021
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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this section be dropped and instead we should point to the error categories inventory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still a good intro for getting started.


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 @@ -15,7 +15,7 @@ import "google/protobuf/timestamp.proto";
// Status: experimental interface, will change before it is deemed production
// ready
//
// Ledger configuration management service provides methods for the ledger administrator
// 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.
service ConfigManagementService {
Expand All @@ -34,9 +34,10 @@ service ConfigManagementService {
// does not match the current active configuration generation. The caller is expected
// to retry by again fetching current time model using 'GetTimeModel', applying changes
// and resubmitting.
// - ``ABORTED``: if the request is rejected or times out. Note that a timed out request may
// - ``DEADLINE_EXCEEDED``: if the request times out. Note that a timed out request may
// have still been committed to the ledger. Application should re-query the current
// time model before retrying.
// - ``FAILED_PRECONDITION``: if the request is rejected.
// - ``UNIMPLEMENTED``: if this method is not supported by the backing ledger.
rpc SetTimeModel (SetTimeModelRequest) returns (SetTimeModelResponse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,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 yet able to prune at the specified offset.
//
// Other GRPC errors can be returned depending on the type of condition preventing a prune:
// - ``OUT_OF_RANGE``: if the participant is not yet able to prune at the specified offset, but without user intervention
// the offset will eventually be usable for pruning.
// - ``FAILED_PRECONDITION`` if some sort of user intervention is required before pruning can proceed at the specified
// offset.
rpc Prune (PruneRequest) returns (PruneResponse);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ service PartyManagementService {
// - ``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
// - ``UNIMPLEMENTED``: if synchronous party allocation is not supported by the backing participant
// - ``DEADLINE_EXCEEDED``: if the request times out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going forward it seems to me we want to thing of signalling errors in terms of error categories, not gRpc status codes. If so, then at some point it could be easier, from maintenance standpoint, to list error categories here instead.

// - ``INVALID_ARGUMENT``: if the provided hint and/or display name is invalid on the given ledger (see below).
// daml-on-sql: suggestion's uniqueness is checked and call rejected if the identifier is already present
// daml-on-kv-ledger: suggestion's uniqueness is checked by the validators in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ service CommandCompletionService {
// 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
// - ``FAILED_PRECONDITION``: if the ledger has been pruned after the subscription start offset
// - ``INVALID_ARGUMENT``: if the payload is malformed or is missing required fields
// - ``OUT_OF_RANGE``: if the absolute offset is not before the end of the ledger
// - ``OUT_OF_RANGE``: if the absolute offset is after the end of the ledger
mziolekda marked this conversation as resolved.
Show resolved Hide resolved
rpc CompletionStream (CompletionStreamRequest) returns (stream CompletionStreamResponse);

// Returns the offset after the latest completion.
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
Loading