use auths_core::error::AuthsErrorInfo;
use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CredentialError {
#[error("issuee identity not found (no KEL): {did}")]
IssueeNotFound {
did: String,
},
#[error("credential registry error: {0}")]
RegistryError(#[source] auths_id::keri::credential_registry::CredentialRegistryError),
#[error("credential already revoked: {said}")]
AlreadyRevoked {
said: String,
},
#[error("issuer is multi-signature (kt≥2); credential anchoring is single-author only")]
KtThresholdUnsupported,
#[error("capability schema unknown or uncomputable")]
SchemaUnknown,
#[error("credential status is stale or unresolvable: {reason}")]
StaleOrUnresolvable {
reason: String,
},
#[error("crypto error: {0}")]
CryptoError(#[source] auths_core::AgentError),
}
impl From<auths_id::keri::credential_registry::CredentialRegistryError> for CredentialError {
fn from(err: auths_id::keri::credential_registry::CredentialRegistryError) -> Self {
use auths_id::keri::credential_registry::CredentialRegistryError as RegErr;
match err {
RegErr::ThresholdUnsupported { .. } => CredentialError::KtThresholdUnsupported,
other => CredentialError::RegistryError(other),
}
}
}
impl From<auths_core::AgentError> for CredentialError {
fn from(err: auths_core::AgentError) -> Self {
CredentialError::CryptoError(err)
}
}
impl AuthsErrorInfo for CredentialError {
fn error_code(&self) -> &'static str {
match self {
Self::IssueeNotFound { .. } => "AUTHS-E6101",
Self::RegistryError(_) => "AUTHS-E6102",
Self::AlreadyRevoked { .. } => "AUTHS-E6103",
Self::KtThresholdUnsupported => "AUTHS-E6104",
Self::SchemaUnknown => "AUTHS-E6105",
Self::StaleOrUnresolvable { .. } => "AUTHS-E6106",
Self::CryptoError(e) => e.error_code(),
}
}
fn suggestion(&self) -> Option<&'static str> {
match self {
Self::IssueeNotFound { .. } => Some(
"The issuee must have an incepted identity (KEL) before it can be credentialed",
),
Self::RegistryError(_) => {
Some("Check the issuer identity and registry storage are reachable")
}
Self::AlreadyRevoked { .. } => {
Some("This credential is already revoked; no further action is needed")
}
Self::KtThresholdUnsupported => {
Some("Credential issuance currently requires a single-signature (kt=1) issuer")
}
Self::SchemaUnknown => {
Some("The compiled-in capability schema is unavailable; this is a build defect")
}
Self::StaleOrUnresolvable { .. } => Some(
"No fresh witnessed tip was reachable; sync the issuer KEL/receipts and retry, or relax --require-witnesses",
),
Self::CryptoError(e) => e.suggestion(),
}
}
}