use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;
use std::error::Error;
use std::fmt::{self, Display};
use apollo_federation_types::build::{BuildError, BuildErrorNode};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub(crate) struct CompositionError {
message: Option<String>,
#[serde(flatten)]
extensions: Option<JsCompositionErrorExtensions>,
code: Option<String>,
nodes: Option<Vec<BuildErrorNode>>,
omitted_nodes_count: Option<u32>,
}
impl Display for CompositionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let code = if let Some(extensions) = &self.extensions {
&extensions.code
} else {
"UNKNOWN"
};
if let Some(message) = &self.message {
write!(f, "{}: {}", code, &message)
} else {
write!(f, "{code}")
}
}
}
impl From<CompositionError> for BuildError {
fn from(input: CompositionError) -> Self {
Self::composition_error(
input.code,
input.message,
input.nodes,
input.omitted_nodes_count,
)
}
}
impl Error for CompositionError {}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub(crate) struct JsCompositionErrorExtensions {
code: String,
#[serde(flatten)]
other: BTreeMap<String, Value>,
}