Errors
Every call returns dinio_sdk::Result<T>, with one error type:
pub enum Error { /// The API refused the request. Api(ApiError), /// No response: DNS, TLS, connection, timeout. Transport(reqwest::Error), /// The response was not the API's (e.g. a proxy error page). Decode { status: u16, snippet: String }, /// Rejected by the SDK before sending (bad URL, bad argument). InvalidInput(String), /// An `ops` function found nothing to act on. NotFound(String),}
pub struct ApiError { pub status: u16, pub code: ErrorCode, pub message: String, pub details: Option<serde_json::Value>, // e.g. violated zone rules on 409 / 422}ErrorCode mirrors the API’s error.code: Unauthenticated,
InvalidApiKey, InvalidToken, Forbidden, Suspended, NotFound, Conflict,
ManagedRecord, ManagedCertificate, Validation, ImportFailed, DiscoveryFailed,
PayloadTooLarge, AuditDisabled, TelemetryDisabled, BadRequest, Internal, and
Other(String) for codes this SDK version doesn’t know. It is #[non_exhaustive]: later versions add variants for new
codes, so a match needs a wildcard arm.
For ManagedRecord and ManagedCertificate, ApiError::managed() returns
Some((managed_by, name)) — what keeps the resource, and the redirect’s name:
match client.records().delete(value_id).await { Err(Error::Api(err)) if err.code == ErrorCode::ManagedRecord => { if let Some((managed_by, name)) = err.managed() { eprintln!("kept by {managed_by} for {name}: delete the redirect instead"); } } other => other?,}use dinio_sdk::{Error, ErrorCode};
match client.zones().create("example.com").await { Ok(created) => println!("created {}", created.value.uuid), Err(Error::Api(err)) if err.code == ErrorCode::Conflict => println!("already exists"), Err(err) => return Err(err.into()),}For the package errors, ApiError::plan_limit() returns a
PlanLimit { key, limit, used, requested } for ErrorCode::PlanLimit, and
ApiError::subscription_line() the line ("auth" or "filter") for
ErrorCode::NoSubscription:
match client.client_identities().create(&identity).await { Err(Error::Api(err)) if err.code == ErrorCode::PlanLimit => { if let Some(limit) = err.plan_limit() { eprintln!("{}: limit {}, in use {:?}", limit.key, limit.limit, limit.used); } } Err(Error::Api(err)) if err.code == ErrorCode::NoSubscription => { eprintln!("choose a {} package first", err.subscription_line().unwrap_or("?")); } other => { other?; }}For ImportFailed, ApiError::import_report() returns the
import report: what was refused, by line or
entry.
The SDK never panics on API or transport errors and never prints anything. Errors implement
std::error::Error and Display with the API’s message, code and HTTP status:
Zone not found (NOT_FOUND, HTTP 404)