use crate::subnet_catalog::RoutingRange;
use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
pub enum CatalogError {
#[error(transparent)]
Json(#[from] serde_json::Error),
#[error("unsupported subnet catalog schema version {found}; supported version is {supported}")]
UnsupportedSchemaVersion { found: u32, supported: u32 },
#[error("subnet catalog network is {actual:?}; expected {expected:?}")]
NetworkMismatch {
expected: String,
actual: String,
},
#[error("subnet catalog Registry canister is {actual}; expected {expected}")]
RegistryCanisterMismatch {
expected: String,
actual: String,
},
#[error("subnet catalog Registry version must be greater than zero")]
InvalidRegistryVersion,
#[error("subnet catalog must contain at least one subnet")]
EmptySubnets,
#[error("subnet catalog must contain at least one routing range")]
EmptyRoutingRanges,
#[error("invalid principal in {field}: {value}: {reason}")]
InvalidPrincipal {
field: &'static str,
value: String,
reason: String,
},
#[error("duplicate subnet principal in catalog: {subnet_principal}")]
DuplicateSubnet { subnet_principal: String },
#[error("noncanonical subnet order: {previous} must sort before {current}")]
NonCanonicalSubnetOrder {
previous: String,
current: String,
},
#[error("routing range references unknown subnet: {subnet_principal}")]
UnknownRoutingSubnet { subnet_principal: String },
#[error(
"invalid routing range for {subnet_principal}: start {start_canister_id} sorts after end {end_canister_id}"
)]
InvalidRoutingRange {
subnet_principal: String,
start_canister_id: String,
end_canister_id: String,
},
#[error("overlapping routing ranges: {first} overlaps {second}")]
OverlappingRoutingRanges {
first: Box<RoutingRange>,
second: Box<RoutingRange>,
},
#[error("noncanonical routing range order: {previous} must sort before {current}")]
NonCanonicalRoutingOrder {
previous: Box<RoutingRange>,
current: Box<RoutingRange>,
},
#[error(
"subnet {subnet_principal} kind {actual} contradicts Registry subnet_type={registry_subnet_type}; expected {expected}"
)]
SubnetKindMismatch {
subnet_principal: String,
registry_subnet_type: i32,
expected: String,
actual: String,
},
#[error(
"subnet {subnet_principal} charges_apply_by_default={actual} contradicts expected {expected}"
)]
ChargingPolicyMismatch {
subnet_principal: String,
expected: bool,
actual: bool,
},
#[error("subnet {subnet_principal} classification field {field} is invalid: {reason}")]
ClassificationMismatch {
subnet_principal: String,
field: &'static str,
reason: String,
},
#[error("invalid catalog timestamp in {field}: {value:?}")]
InvalidTimestamp {
field: &'static str,
value: String,
},
#[error(
"catalog timestamp in {field} is in the future: {value}; latest accepted unix time is {latest_allowed_unix_secs}"
)]
FutureTimestamp {
field: &'static str,
value: String,
latest_allowed_unix_secs: u64,
},
#[error("invalid catalog source endpoint {endpoint:?}: {reason}")]
InvalidSourceEndpoint {
endpoint: String,
reason: String,
},
#[error("invalid catalog provenance field {field}: {reason}")]
InvalidProvenance {
field: &'static str,
reason: String,
},
#[error(
"unsupported catalog assurance {assurance}; this build validates uncertified_query and multi_endpoint_agreement evidence"
)]
UnsupportedAssurance {
assurance: String,
},
#[error("classification policy schema {found} is unsupported; expected {supported}")]
ClassificationPolicyVersionMismatch {
found: u32,
supported: u32,
},
#[error("classification policy digest mismatch: found {actual}; expected {expected}")]
ClassificationPolicyDigestMismatch {
expected: String,
actual: String,
},
#[error(
"resolver policy mismatch: version {actual_version} backend {actual_backend:?}; expected version {expected_version} backend {expected_backend:?}"
)]
ResolverPolicyMismatch {
expected_version: u32,
actual_version: u32,
expected_backend: String,
actual_backend: String,
},
#[error("invalid catalog digest {value:?}; expected 64 lowercase hexadecimal characters")]
InvalidCatalogDigest {
value: String,
},
#[error(
"invalid catalog agreement digest {value:?}; expected 64 lowercase hexadecimal characters"
)]
InvalidAgreementDigest {
value: String,
},
#[error("catalog agreement digest mismatch: found {actual}; expected {expected}")]
AgreementDigestMismatch {
expected: String,
actual: String,
},
#[error("catalog digest mismatch: found {actual}; expected {expected}")]
CatalogDigestMismatch {
expected: String,
actual: String,
},
#[error("subnet principal {subnet_principal} was not found in the cached catalog")]
UnknownSubnet { subnet_principal: String },
#[error("principal prefix {prefix:?} did not match cached subnet principals")]
PrincipalPrefixNotFound { prefix: String },
#[error("principal prefix {prefix:?} is ambiguous; matches: {matches:?}")]
AmbiguousPrincipalPrefix {
prefix: String,
matches: Vec<String>,
},
#[error(
"canister principal {canister_principal} was not covered by cached routing ranges at registry_version={registry_version}, catalog_schema_version={catalog_schema_version}"
)]
RouteNotFound {
canister_principal: String,
registry_version: u64,
catalog_schema_version: u32,
},
}