Error handling

Version 0.6.0 Updated Nov 12, 2025

load and load_and_merge_subcommand_for return OrthoResult<T>, an alias for Result<T, Arc<OrthoError>>. OrthoError wraps errors from clap, file I/O and figment. Failures during the final merge of CLI values over configuration sources surface as the Merge variant, providing clearer diagnostics when the combined data is invalid. When multiple sources fail, the errors are collected into the Aggregate variant so callers can inspect each individual failure. Consumers should handle these errors appropriately, for example by printing them to stderr and exiting. If required fields are missing after merging, the crate returns OrthoError::MissingRequiredValues with a user‑friendly list of missing paths and hints on how to provide them. For example:

Missing required values:
  sample_value (use --sample-value, SAMPLE_VALUE, or file entry)

Aggregating multiple errors

To return multiple errors in one go, use OrthoError::aggregate. It accepts any iterator of items that can be converted into Arc<OrthoError> so both owned and shared errors are supported. If the list might be empty, OrthoError::try_aggregate returns Option<OrthoError> instead of panicking:

use std::sync::Arc;
use ortho_config::OrthoError;

// From bare errors
let err = OrthoError::aggregate(vec![
    OrthoError::Validation { key: "port".into(), message: "must be positive".into() },
    OrthoError::gathering(figment::Error::from("invalid")),
]);

// From shared errors
let err = OrthoError::aggregate(vec![
    Arc::new(OrthoError::Validation { key: "x".into(), message: "bad".into() }),
    OrthoError::gathering_arc(figment::Error::from("boom")),
]);

Mapping errors ergonomically

To reduce boiler‑plate when converting between error types, the crate exposes small extension traits:

  • OrthoResultExt::into_ortho() converts Result<T, E> into OrthoResult<T> when E: Into<OrthoError> (e.g., serde_json::Error).
  • OrthoMergeExt::into_ortho_merge() converts Result<T, figment::Error> into OrthoResult<T> as OrthoError::Merge.
  • IntoFigmentError::into_figment() converts Arc<OrthoError> (or &Arc<OrthoError>) into figment::Error for interop in tests or adapters, cloning the inner error to preserve structured details where possible.
  • ResultIntoFigment::to_figment() converts OrthoResult<T> into Result<T, figment::Error>.

Examples:

use ortho_config::{OrthoMergeExt, OrthoResultExt, ResultIntoFigment};

fn sanitize<T: serde::Serialize>(v: &T) -> ortho_config::OrthoResult<serde_json::Value> {
    serde_json::to_value(v).into_ortho()
}

fn extract(fig: figment::Figment) -> ortho_config::OrthoResult<MyCfg> {
    fig.extract::<MyCfg>().into_ortho_merge()
}

fn interop(r: ortho_config::OrthoResult<MyCfg>) -> Result<MyCfg, figment::Error> {
    r.to_figment()
}