Skip to main content

ic_query/sns/report/model/
errors.rs

1//! Module: sns::report::model::errors
2//!
3//! Responsibility: typed SNS report and source errors.
4//! Does not own: command usage errors, clap parsing, or text rendering.
5//! Boundary: carries recoverable report-builder failures to command runners.
6
7use crate::{cache_file::CacheFileError, runtime::RuntimeError};
8use std::{io, path::PathBuf};
9use thiserror::Error as ThisError;
10
11///
12/// SnsHostError
13///
14/// Typed error returned by SNS report builders, live sources, and cache reads.
15///
16
17#[derive(Debug, ThisError)]
18pub enum SnsHostError {
19    #[error(
20        "`icq sns` supports only the mainnet `ic` network\n\nThe SNS list is queried from the public Internet Computer mainnet SNS-W canister.\nLocal replica SNS discovery is not implemented yet.\n\nTry:\n  icq --network ic sns list"
21    )]
22    UnsupportedNetwork { network: String },
23
24    #[error("failed to create Tokio runtime for SNS query: {0}")]
25    Runtime(#[from] RuntimeError),
26
27    #[error("failed to build IC agent for endpoint {endpoint}: {reason}")]
28    AgentBuild { endpoint: String, reason: String },
29
30    #[error("invalid {field}: {reason}")]
31    InvalidPrincipal { field: &'static str, reason: String },
32
33    #[error("failed to encode Candid request for {message}: {reason}")]
34    CandidEncode {
35        message: &'static str,
36        reason: String,
37    },
38
39    #[error("SNS query method {method} failed: {reason}")]
40    AgentCall {
41        method: &'static str,
42        reason: String,
43    },
44
45    #[error("SNS governance method {method} returned error {error_type}: {message}")]
46    GovernanceError {
47        method: &'static str,
48        error_type: i32,
49        message: String,
50    },
51
52    #[error("SNS governance method {method} returned no result")]
53    MissingGovernanceResult { method: &'static str },
54
55    #[error("failed to decode Candid response {message}: {reason}")]
56    CandidDecode {
57        message: &'static str,
58        reason: String,
59    },
60
61    #[error("SNS list id {id} is out of range; list contains {sns_count} deployed SNS instances")]
62    UnknownSnsId { id: usize, sns_count: usize },
63
64    #[error("could not find deployed SNS with root principal {root_canister_id}")]
65    UnknownSnsRoot { root_canister_id: String },
66
67    #[error("SNS lookup input must be a list id or root principal: {input}")]
68    InvalidLookup { input: String },
69
70    #[error(
71        "SNS neurons cache is missing at {}\n\nRun `icq sns neurons refresh <id|root-principal>` to fetch a complete snapshot before using cache-backed sorting.",
72        path.display()
73    )]
74    MissingNeuronsCache { path: PathBuf },
75
76    #[error(
77        "SNS neurons cache is missing for SNS list id {id} under {}\n\nRun `icq sns neurons refresh {id}` to fetch a complete snapshot before using cache-backed sorting.",
78        root.display()
79    )]
80    MissingNeuronsCacheForId { id: usize, root: PathBuf },
81
82    #[error(
83        "SNS proposals cache is missing at {}\n\nRun `icq sns proposals refresh <id|root-principal>` to fetch a complete snapshot.",
84        path.display()
85    )]
86    MissingProposalsCache { path: PathBuf },
87
88    #[error("failed to read SNS cache at {}: {source}", path.display())]
89    ReadCache { path: PathBuf, source: io::Error },
90
91    #[error("failed to parse SNS cache at {}: {source}", path.display())]
92    ParseCache {
93        path: PathBuf,
94        source: serde_json::Error,
95    },
96
97    #[error("failed to serialize SNS cache JSON for {}: {source}", path.display())]
98    SerializeCache {
99        path: PathBuf,
100        source: serde_json::Error,
101    },
102
103    #[error("unsupported SNS cache schema version {version}; expected {expected}")]
104    UnsupportedCacheSchemaVersion { version: u32, expected: u32 },
105
106    #[error("cached SNS network mismatch: path is for {requested}, report is for {actual}")]
107    CacheNetworkMismatch { requested: String, actual: String },
108
109    #[error(
110        "cached SNS snapshot identity mismatch at {}: {field} is {actual}, expected {expected}",
111        path.display()
112    )]
113    CacheIdentityMismatch {
114        path: PathBuf,
115        field: &'static str,
116        expected: String,
117        actual: String,
118    },
119
120    #[error("SNS cache operation failed: {0}")]
121    Cache(#[from] CacheFileError),
122
123    #[error(
124        "SNS neurons refresh did not publish a complete snapshot after {pages_fetched} pages and {rows_fetched} rows: {reason}"
125    )]
126    IncompleteRefresh {
127        pages_fetched: u32,
128        rows_fetched: usize,
129        reason: String,
130    },
131
132    #[error("SNS cache root is required for cache-backed neuron reports")]
133    MissingCacheRoot,
134
135    #[error("unsupported SNS proposal view: {reason}")]
136    UnsupportedProposalView { reason: String },
137}