Skip to main content

Error

Enum Error 

Source
#[non_exhaustive]
pub enum Error { Transport(Box<Error>), Connection(String), Status(Box<Status>), Http { status: u16, body: String, }, Json(Box<Error>), CommandRejected { code: String, message: String, }, Auth(String), InvalidRequest(String), UnexpectedResponse(String), Timeout, Payload(Box<dyn Error + Send + Sync>), }
Expand description

The single error type for the whole Canton Rust SDK.

It is #[non_exhaustive] so new variants can be added without a breaking change. Large upstream error types are boxed so that Result<T, Error> stays cheap to move on the happy path.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Transport(Box<Error>)

gRPC transport failure (DNS, TCP, TLS, HTTP/2). Retriable.

§

Connection(String)

A non-gRPC connection failure (e.g. an HTTP/JSON or token-endpoint request that could not be sent). Retriable.

§

Status(Box<Status>)

The server returned a gRPC status. The full tonic::Status is kept so callers can inspect the code, message, and metadata; see Error::code.

§

Http

A non-success HTTP response from the JSON API or a token endpoint. Retriable for transient status codes (see Error::is_retriable).

Fields

§status: u16

The HTTP status code.

§body: String

The response body (truncated by the caller if large).

§

Json(Box<Error>)

JSON (de)serialization error.

§

CommandRejected

A command was rejected by the ledger for business/interpretation reasons (as opposed to a transport failure). Not retriable: this is a terminal outcome of that submission read back from the completion stream, and re-submitting is an application decision — the automatic retry path (submit* RPC errors) surfaces rejections as Error::Status instead, with full category/retry-delay precision.

Fields

§code: String

The rejection status code.

§message: String

The rejection message.

§

Auth(String)

Authentication/authorization was rejected (bad or expired credentials). Not retriable — a token-transport failure surfaces as Error::Connection or Error::Http instead.

§

InvalidRequest(String)

A request precondition or configuration value was invalid before send.

§

UnexpectedResponse(String)

The server’s response was well-formed at the transport level but not what the protocol expects (e.g. a missing field, or a stream that ended unexpectedly). Not a caller-input error.

§

Timeout

The operation exceeded its configured deadline. Retriable.

§

Payload(Box<dyn Error + Send + Sync>)

A typed payload failed to convert to or from the Ledger API Value — a canton-daml codec error. Not retriable: the shape will not change on a retry.

Implementations§

Source§

impl Error

Source

pub fn code(&self) -> Option<Code>

The gRPC status code the participant answered with, on either transport.

The JSON Ledger API reports it numerically as grpcCodeValue, so the same failure yields the same code whichever lane carried it — the HTTP status alone does not, since Canton maps several codes onto one status. None when there is no participant verdict to report: a transport failure, a timeout, or an HTTP body that is not a Canton error object (a proxy’s error page, say).

Source

pub fn is_retriable(&self) -> bool

Whether retrying the operation may succeed.

For gRPC statuses, Canton’s own verdict wins: every Ledger API error carries an ErrorCategory whose retryability is defined by the error-code documentation, and retryable errors additionally carry a google.rpc.RetryInfo detail. Only when a status carries neither (a proxy in the middle, a non-Canton server) does the classification fall back to the transient gRPC codes (Unavailable, DeadlineExceeded, ResourceExhausted, Aborted).

Beyond statuses, transient conditions are retriable: timeouts, transport/connection failures, and transient HTTP status codes (408, 429, 5xx). Everything else — invalid input, auth rejection, command rejection, NotFound/AlreadyExists, deserialization — is not.

Source

pub fn category(&self) -> Option<ErrorCategory>

The Canton ErrorCategory of this error, when it carries one: from ErrorInfo.metadata["category"] on a gRPC status, or the errorCategory field of a JSON API error body. This is the field the error-code documentation tells clients to base error handling on; Error::is_retriable already does.

Source

pub fn retry_delay(&self) -> Option<Duration>

The server-recommended delay before retrying, from the google.rpc.RetryInfo detail of a gRPC status or the retryInfo field of a JSON API error body. Canton attaches it to retryable errors; the retry helper (crate::retry::run_with_retry) already honours it.

Source

pub fn correlation_id(&self) -> Option<String>

The correlation id of the failed request, from the google.rpc.RequestInfo detail of a gRPC status or the correlationId/traceId of a JSON API error body. Canton echoes it in every error; quote it when reporting a problem to the participant’s operator, who can find the server-side trace by it.

Source

pub fn resource_info(&self) -> Vec<ResourceInfo>

The resources this error is about: which contract, package, party or synchronizer the participant is complaining of. Canton attaches these to the errors where “which one?” is the first question — CONTRACT_NOT_FOUND names the contract id, contention names the locked contracts.

A Vec rather than an Option because the wire carries a list: the JSON Ledger API’s resources is an array of [type, name] pairs, and one error can name several. The gRPC side yields at most one today — that is a limit of tonic_types, which models a single google.rpc.ResourceInfo detail, not of the protocol.

Source

pub fn error_info(&self) -> Option<ErrorInfo>

The machine-readable identity of the failure: Canton’s error reason (e.g. DUPLICATE_COMMAND) plus its context metadata. Prefer it over string-matching Display output.

Available on either transport. gRPC carries it as a google.rpc.ErrorInfo detail; the JSON Ledger API spells the same two things as code and context, and this reads whichever is there. That matters because the alternative on the JSON lane was the string matching this method exists to replace.

None when the participant published no identity to report: a transport failure, a status without the detail, or a redacted error — Canton answers a security-sensitive failure with the literal "NA", which is the absence of an error id rather than an error id.

domain is empty on the JSON lane, and Canton leaves it empty on gRPC too.

Trait Implementations§

Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for Error

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for Error

Source§

fn from(err: Error) -> Error

Converts to this type from the input type.
Source§

impl From<Error> for Error

Source§

fn from(err: Error) -> Error

Converts to this type from the input type.
Source§

impl From<Status> for Error

Source§

fn from(status: Status) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl !UnwindSafe for Error

§

impl Freeze for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnsafeUnpin for Error

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more