#[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
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
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.
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
impl Error
Sourcepub fn code(&self) -> Option<Code>
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).
Sourcepub fn is_retriable(&self) -> bool
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.
Sourcepub fn category(&self) -> Option<ErrorCategory>
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.
Sourcepub fn retry_delay(&self) -> Option<Duration>
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.
Sourcepub fn correlation_id(&self) -> Option<String>
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.
Sourcepub fn resource_info(&self) -> Vec<ResourceInfo>
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.
Sourcepub fn error_info(&self) -> Option<ErrorInfo>
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 Error for Error
impl Error for Error
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request