Skip to main content

daml_grpc/data/
error.rs

1use std::io;
2use tonic::codegen::http;
3
4/// A Daml ledger error.
5#[derive(Debug, thiserror::Error)]
6pub enum DamlError {
7    #[error("timeout error: {0}")]
8    TimeoutError(#[source] Box<DamlError>),
9    #[error(transparent)]
10    GrpcTransportError(#[from] tonic::transport::Error),
11    #[error(transparent)]
12    GrpcStatusError(tonic::Status),
13    #[error(transparent)]
14    GrpcPermissionError(tonic::Status),
15    #[error(transparent)]
16    InvalidUriError(#[from] http::uri::InvalidUri),
17    #[error(transparent)]
18    StdError(#[from] io::Error),
19    #[error("unexpected type, expected {0} but found {1}")]
20    UnexpectedType(String, String),
21    #[error("unknown field {0}")]
22    UnknownField(String),
23    #[error("list index {0} out of range")]
24    ListIndexOutOfRange(usize),
25    #[error("expected optional value is None")]
26    MissingRequiredField,
27    #[error("unexpected variant constructor, expected {0} but found {1}")]
28    UnexpectedVariant(String, String),
29    #[error("{0}")]
30    Other(String),
31    #[error("failed conversion: {0}")]
32    FailedConversion(String),
33    #[error("insufficient parties")]
34    InsufficientParties,
35}
36
37impl DamlError {
38    pub fn new_failed_conversion(msg: impl Into<String>) -> Self {
39        DamlError::FailedConversion(msg.into())
40    }
41
42    pub fn new_timeout_error(inner: DamlError) -> Self {
43        DamlError::TimeoutError(Box::new(inner))
44    }
45}
46
47/// `tonic::Status` maps to one of two variants depending on its code —
48/// permission-vs-authn errors get their own bucket so downstream code
49/// can pattern-match on it without inspecting the status code.
50impl From<tonic::Status> for DamlError {
51    fn from(e: tonic::Status) -> Self {
52        match e.code() {
53            tonic::Code::PermissionDenied | tonic::Code::Unauthenticated => DamlError::GrpcPermissionError(e),
54            _ => DamlError::GrpcStatusError(e),
55        }
56    }
57}
58
59impl From<&str> for DamlError {
60    fn from(e: &str) -> Self {
61        DamlError::Other(e.to_owned())
62    }
63}
64
65impl From<bigdecimal::ParseBigDecimalError> for DamlError {
66    fn from(e: bigdecimal::ParseBigDecimalError) -> Self {
67        DamlError::FailedConversion(e.to_string())
68    }
69}
70
71/// A Daml ledger result.
72pub type DamlResult<T> = ::std::result::Result<T, DamlError>;