///|
/// RFC 8555 uses problem documents for protocol failures. Subproblems preserve
/// per-identifier diagnostics without flattening them into one message.
pub(all) struct AcmeSubproblem {
kind : String
detail : String
identifier : Identifier?
} derive(Eq, Debug)
///|
pub(all) struct AcmeProblem {
kind : String
title : String?
detail : String
status : Int?
instance : String?
subproblems : Array[AcmeSubproblem]
} derive(Eq, Debug)
///|
pub(all) suberror AcmeError {
Malformed(stage~ : String, detail~ : String)
Protocol(problem~ : AcmeProblem)
MissingNonce
RetryExhausted(attempts~ : Int)
InvalidState(expected~ : String, actual~ : String)
Unsupported(feature~ : String)
} derive(Eq, Debug)
///|
/// Stable human-readable text for logs and command-line adapters.
pub fn AcmeError::message(self : AcmeError) -> String {
match self {
Malformed(stage~, detail~) => stage + ": " + detail
Protocol(problem~) => problem.detail
MissingNonce => "no replay nonce is available"
RetryExhausted(attempts~) =>
"retry limit reached after \{attempts} attempts"
InvalidState(expected~, actual~) =>
"expected " + expected + ", got " + actual
Unsupported(feature~) => "unsupported: " + feature
}
}