cu_profiler_core/error.rs
1//! Typed error model for `cu-profiler-core`.
2//!
3//! Errors are actionable: parser failures carry the offending log line index and
4//! the concrete reason, so a caller can render a message like
5//! `Failed to parse compute-unit line at log index 42: expected integer after
6//! "consumed"` rather than a bare `parse failed`.
7
8use std::fmt;
9
10/// The result type used throughout the core crate.
11pub type Result<T> = std::result::Result<T, Error>;
12
13/// All error conditions the core can surface.
14///
15/// Variants map onto the documented CLI exit codes (see the `cu-profiler-cli`
16/// crate) so the boundary layer can translate an [`Error`] into a stable code.
17#[derive(Debug, thiserror::Error)]
18#[non_exhaustive]
19pub enum Error {
20 /// The configuration file was missing, malformed, or semantically invalid.
21 #[error("configuration error: {0}")]
22 Config(String),
23
24 /// A Solana log line could not be parsed. Carries enough context to locate
25 /// and explain the failure.
26 #[error("failed to parse {what} at log index {index}: {reason}")]
27 Parse {
28 /// What the parser was trying to read (e.g. `"compute-unit line"`).
29 what: String,
30 /// Zero-based index of the offending line within the log stream.
31 index: usize,
32 /// Why parsing failed, in plain language.
33 reason: String,
34 },
35
36 /// A simulation backend failed to execute a scenario.
37 #[error("simulation failure: {0}")]
38 Simulation(String),
39
40 /// A baseline could not be read, written, or compared.
41 #[error("baseline error: {0}")]
42 Baseline(String),
43
44 /// A backend exists as an interface but is not implemented in this build.
45 #[error("execution backend `{0}` is not implemented in this build")]
46 BackendUnimplemented(String),
47
48 /// An underlying I/O failure.
49 #[error("i/o error: {0}")]
50 Io(#[from] std::io::Error),
51
52 /// A TOML (de)serialization failure, kept as a string so the error type
53 /// stays independent of the `toml` error representation.
54 #[error("toml error: {0}")]
55 Toml(String),
56
57 /// A JSON (de)serialization failure.
58 #[cfg(feature = "json")]
59 #[error("json error: {0}")]
60 Json(#[from] serde_json::Error),
61}
62
63impl Error {
64 /// Build a [`Error::Parse`] without repeating the field names at call sites.
65 pub fn parse(what: impl fmt::Display, index: usize, reason: impl fmt::Display) -> Self {
66 Self::Parse {
67 what: what.to_string(),
68 index,
69 reason: reason.to_string(),
70 }
71 }
72}
73
74impl From<toml::de::Error> for Error {
75 fn from(e: toml::de::Error) -> Self {
76 Self::Toml(e.to_string())
77 }
78}