Skip to main content

surge_io/cgmes/
error.rs

1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2use std::path::PathBuf;
3
4use thiserror::Error;
5
6// ---------------------------------------------------------------------------
7// Error type
8// ---------------------------------------------------------------------------
9
10#[derive(Error, Debug)]
11pub enum CgmesError {
12    #[error("cannot read CGMES directory {path}: {source}")]
13    ReadDirectory {
14        path: PathBuf,
15        #[source]
16        source: std::io::Error,
17    },
18    #[error("cannot read directory entry in {path}: {source}")]
19    ReadDirectoryEntry {
20        path: PathBuf,
21        #[source]
22        source: std::io::Error,
23    },
24    #[error("no CGMES XML profiles found in {path}")]
25    NoProfiles { path: PathBuf },
26    #[error("cannot open CGMES archive {path}: {source}")]
27    OpenArchive {
28        path: PathBuf,
29        #[source]
30        source: std::io::Error,
31    },
32    #[error("cannot read CGMES zip archive {path}: {source}")]
33    ReadArchive {
34        path: PathBuf,
35        #[source]
36        source: zip::result::ZipError,
37    },
38    #[error("cannot read zip entry in {path}: {source}")]
39    ReadArchiveEntry {
40        path: PathBuf,
41        #[source]
42        source: zip::result::ZipError,
43    },
44    #[error("cannot create temporary directory for CGMES archive extraction: {0}")]
45    CreateTempDir(#[source] std::io::Error),
46    #[error("cannot extract archive entry to {path}: {source}")]
47    ExtractArchiveEntry {
48        path: PathBuf,
49        #[source]
50        source: std::io::Error,
51    },
52    #[error("zip archive {archive_path} contains an unsafe CGMES entry path: {entry_name}")]
53    InvalidArchiveEntryPath {
54        archive_path: PathBuf,
55        entry_name: String,
56    },
57    #[error("zip archive {archive_path} contains duplicate CGMES profile paths: {entry_name}")]
58    DuplicateArchiveEntryPath {
59        archive_path: PathBuf,
60        entry_name: String,
61    },
62    #[error("unsupported CGMES input: {0}")]
63    UnsupportedInput(String),
64    #[error("I/O error: {0}")]
65    Io(#[from] std::io::Error),
66    #[error("XML error: {0}")]
67    Xml(#[from] quick_xml::Error),
68    #[error(
69        "CGMES dataset is missing the SSH operating-point profile; include SSH for generator/load/converter set-points"
70    )]
71    MissingSshProfile,
72    #[error(
73        "CGMES dataset contains {count} unresolved BaseVoltage reference(s): {examples:?}. \
74         Include the referenced EQ/EQBD BaseVoltage objects before loading."
75    )]
76    MissingBaseVoltageReferences { count: usize, examples: Vec<String> },
77    #[error(
78        "no TopologicalNodes found — include a TP profile, or provide a bus-breaker model \
79         (ConnectivityNode + Switch) so topology can be synthesized automatically"
80    )]
81    NoTopology,
82    /// CIM-03: object store size cap exceeded (protects against >1 GB allocations from
83    /// malformed or adversarial CIM files).
84    #[error("CIM file contains too many objects: {0}")]
85    TooManyObjects(String),
86}