use semantic_memory_forge::ExportEnvelopeError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum BridgeError {
#[error("invalid envelope: {reason}")]
InvalidEnvelope { reason: String },
#[error("incompatible version: expected {expected}, got {actual}")]
IncompatibleVersion { expected: String, actual: String },
#[error("digest mismatch: expected {expected}, got {actual}")]
DigestMismatch { expected: String, actual: String },
#[error("digest computation failed: {reason}")]
DigestComputationFailed { reason: String },
#[error("invalid record: {reason}")]
InvalidRecord { reason: String },
#[error("transform failed: {reason}")]
TransformFailed { reason: String },
#[error("missing episode identity in legacy import: {record_context}")]
MissingEpisodeIdentity { record_context: String },
}
impl BridgeError {
pub fn kind(&self) -> &'static str {
match self {
Self::InvalidEnvelope { .. } => "invalid_envelope",
Self::IncompatibleVersion { .. } => "incompatible_version",
Self::DigestMismatch { .. } => "digest_mismatch",
Self::DigestComputationFailed { .. } => "digest_computation_failed",
Self::InvalidRecord { .. } => "invalid_record",
Self::TransformFailed { .. } => "transform_failed",
Self::MissingEpisodeIdentity { .. } => "missing_episode_identity",
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct BridgeImportFailureArtifact {
pub schema_version: String,
pub source_envelope_id: String,
pub source_authority: String,
pub scope_namespace: String,
pub error_kind: String,
pub error_message: String,
pub failed_at: String,
}
pub const BRIDGE_IMPORT_FAILURE_ARTIFACT_V1_SCHEMA: &str = "bridge_import_failure_artifact_v1";
impl BridgeImportFailureArtifact {
pub fn from_error(
error: &BridgeError,
source_envelope_id: &str,
source_authority: &str,
scope_namespace: &str,
) -> Self {
Self {
schema_version: BRIDGE_IMPORT_FAILURE_ARTIFACT_V1_SCHEMA.into(),
source_envelope_id: source_envelope_id.into(),
source_authority: source_authority.into(),
scope_namespace: scope_namespace.into(),
error_kind: error.kind().into(),
error_message: error.to_string(),
failed_at: chrono::Utc::now().to_rfc3339(),
}
}
}
impl From<ExportEnvelopeError> for BridgeError {
fn from(value: ExportEnvelopeError) -> Self {
match value {
ExportEnvelopeError::InvalidEnvelope { reason } => Self::InvalidEnvelope { reason },
ExportEnvelopeError::IncompatibleVersion { expected, actual } => {
Self::IncompatibleVersion { expected, actual }
}
ExportEnvelopeError::DigestMismatch { expected, actual } => {
Self::DigestMismatch { expected, actual }
}
ExportEnvelopeError::DigestComputationFailed { reason } => {
Self::DigestComputationFailed { reason }
}
}
}
}