use contextgraph_types::{DataFlow, EgressScope, ErrorCode};
#[derive(Debug, thiserror::Error)]
pub enum HostError {
#[error(
"protocol version mismatch: host speaks {host}, provider {provider} speaks {provider_version}"
)]
VersionMismatch {
host: String,
provider: String,
provider_version: String,
},
#[error("wire encode/decode error: {0}")]
Wire(String),
#[error("transport error talking to provider {id}: {message}")]
Transport { id: String, message: String },
#[error(
"refusing an insecure (plaintext http) transport to non-loopback provider {id} at host `{host}`: TLS is required for any non-loopback provider (C7)"
)]
InsecureTransport { id: String, host: String },
#[error("provider {id} rejected the host credential (HTTP 401 Unauthorized)")]
Unauthorized { id: String },
#[error("provider {id} crashed or closed its stream mid-exchange")]
ProviderCrashed { id: String },
#[error("provider {id} timed out after {timeout_ms}ms")]
Timeout { id: String, timeout_ms: u64 },
#[error(
"provider {id} reported an error{}: {message}",
.code.as_ref().map(|c| format!(" ({c})")).unwrap_or_default()
)]
Provider {
id: String,
code: Option<ErrorCode>,
message: String,
},
#[error(
"provider {id} declares egress and requires one-time consent naming what leaves before it can be queried"
)]
ConsentRequired { id: String, data_flow: DataFlow },
#[error(
"provider {id} declares egress scope(s) {scopes:?} with no recorded consent receipt; the query was not transmitted"
)]
ConsentScopeRequired {
id: String,
scopes: Vec<EgressScope>,
},
#[error("expected a `{expected}` envelope from provider {id}, got `{got}`")]
UnexpectedEnvelope {
id: String,
expected: String,
got: String,
},
#[error("provider {id} broke request correlation: expected id `{expected}`, got `{got}`")]
CorrelationMismatch {
id: String,
expected: String,
got: String,
},
#[error("no provider registered with id `{0}`")]
UnknownProvider(String),
#[error("failed to spawn provider process: {0}")]
Spawn(String),
}