use thiserror::Error;
#[derive(Debug, Error)]
pub enum MilsymbolError {
#[error("Failed to serialize options to JSON")]
SerializationError(#[from] serde_json::Error),
#[error("Failed to execute JavaScript execution within deno_core")]
JsExecutionError(#[source] deno_core::anyhow::Error),
#[error("Could not serialize Rust struct into a V8 object")]
JsSerializationError(#[source] deno_core::serde_v8::Error),
#[error("Could not deserialize the returned V8 value into a Rust struct")]
JsDeserializationError(#[source] deno_core::serde_v8::Error),
#[error("Milsymbol JS runtime initialization failed: {0}")]
RuntimeInitializationError(String),
#[error("Invalid CSS color '{color}'")]
InvalidColor {
color: String,
#[source]
source: csscolorparser::ParseColorError,
},
#[cfg(feature = "image")]
#[error("Failed to render SVG to image")]
ImageRenderingError(#[from] resvg::usvg::Error),
#[cfg(feature = "image")]
#[error("Failed to create pixmap for image rendering")]
PixmapCreationError,
#[cfg(feature = "image")]
#[error("Failed to create RgbaImage from pixmap data")]
RgbaImageCreationError,
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn test_css_parse_color_error_with_context() {
let color = "invalid-color-value-should-cause-an-error";
let parse_err = csscolorparser::Color::from_str(color)
.err()
.expect("Should be able to create a parse error");
let err: eyre::Report = MilsymbolError::InvalidColor {
color: color.to_string(),
source: parse_err,
}
.into();
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("InvalidColor") || debug_str.contains("Invalid CSS color"));
assert!(debug_str.contains(color));
assert!(debug_str.contains("invalid format") || debug_str.contains("color"));
}
#[test]
fn test_error_chaining_js_execution_error() {
let inner_err = deno_core::anyhow::anyhow!("V8 heap allocation failed");
let nested_err = inner_err.context("Failed to run JavaScript");
let err: eyre::Report = MilsymbolError::JsExecutionError(nested_err).into();
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("Failed to execute JavaScript execution"));
assert!(debug_str.contains("Failed to run JavaScript"));
assert!(debug_str.contains("V8 heap allocation failed"));
}
#[test]
fn test_serialization_error_from_serde_json() {
use serde::ser::Error;
let serde_err = serde_json::Error::custom("Object too large");
let err: eyre::Report = MilsymbolError::SerializationError(serde_err).into();
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("Failed to serialize options to JSON"));
assert!(debug_str.contains("Object too large"));
}
#[test]
fn test_js_serialization_error() {
use serde::ser::Error;
let serde_err = deno_core::serde_v8::Error::custom("Value out of range");
let err: eyre::Report = MilsymbolError::JsSerializationError(serde_err).into();
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("Could not serialize Rust struct into a V8 object"));
assert!(debug_str.contains("Value out of range"));
}
}