1use thiserror::Error;
4use zombienet_sdk::OrchestratorError;
5
6#[derive(Error, Debug)]
8pub enum Error {
9 #[error("User aborted due to existing target directory.")]
11 Aborted,
12 #[error("Anyhow error: {0}")]
14 AnyhowError(#[from] anyhow::Error),
15 #[error("Failed to build the chain spec. {0}")]
17 BuildSpecError(String),
18 #[error("Failed to run benchmarking: {0}")]
20 BenchmarkingError(String),
21 #[error("Failed to decode call data. {0}")]
23 CallDataDecodingError(String),
24 #[error("Failed to encode call data. {0}")]
26 CallDataEncodingError(String),
27 #[error("{0}")]
29 CommonError(#[from] pop_common::Error),
30 #[error("Failed to establish a connection to: {0}")]
32 ConnectionFailure(String),
33 #[error("Configuration error: {0}")]
35 Config(String),
36 #[error("Failed to access the current directory")]
38 CurrentDirAccess,
39 #[error("Failed to parse the endowment value")]
41 EndowmentError,
42 #[error("Event {0} not found.")]
44 EventNotFound(String),
45 #[error("Extrinsic submission error: {0}")]
47 ExtrinsicSubmissionError(String),
48 #[error("The dispatchable function is not supported")]
50 FunctionNotSupported,
51 #[error("Genesis builder error: {0}")]
53 GenesisBuilderError(String),
54 #[error("Failed to retrieve image tag.")]
56 ImageTagRetrievalFailed,
57 #[error("IO error: {0}")]
59 IO(#[from] std::io::Error),
60 #[error("JSON error: {0}")]
62 JsonError(#[from] serde_json::Error),
63 #[error("Error parsing metadata for parameter {0}")]
65 MetadataParsingError(String),
66 #[error("Missing binary: {0}")]
68 MissingBinary(String),
69 #[error("Missing chain spec file at: {0}")]
71 MissingChainSpec(String),
72 #[error("Command {command} doesn't exist in binary {binary}")]
74 MissingCommand {
75 command: String,
77 binary: String,
79 },
80 #[error("Orchestrator error: {0}")]
82 OrchestratorError(#[from] OrchestratorError),
83 #[error("Failed to create pallet directory")]
85 PalletDirCreation,
86 #[error("Failed to find the pallet {0}")]
88 PalletNotFound(String),
89 #[error("Failed to process the arguments provided by the user.")]
91 ParamProcessingError,
92 #[error("Failed to parse the arguments provided by the user: {0}")]
94 ParamParsingError(String),
95 #[error("Invalid path")]
97 PathError,
98 #[error("Failed to execute rustfmt")]
100 RustfmtError(std::io::Error),
101 #[error("Failed to find the runtime {0}")]
103 RuntimeNotFound(String),
104 #[error("Template error: {0}")]
106 SourcingError(#[from] pop_common::sourcing::Error),
107 #[error("Subxt error: {0}")]
109 SubXtError(#[from] subxt::Error),
110 #[error("Toml error: {0}")]
112 TomlError(#[from] toml_edit::de::Error),
113 #[error("Failed to test with try-runtime: {0}")]
115 TryRuntimeError(String),
116 #[error("Unsupported command: {0}")]
118 UnsupportedCommand(String),
119 #[error("Failed to locate the workspace")]
121 WorkspaceLocate,
122}
123
124pub(crate) fn handle_command_error<F>(
127 output: &std::process::Output,
128 custom_error: F,
129) -> Result<(), Error>
130where
131 F: FnOnce(String) -> Error,
132{
133 if !output.status.success() {
134 let stderr_msg = String::from_utf8_lossy(&output.stderr);
135 return Err(custom_error(stderr_msg.to_string()));
136 }
137 Ok(())
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143 use anyhow::Result;
144 use std::{
145 os::unix::process::ExitStatusExt,
146 process::{ExitStatus, Output},
147 };
148
149 #[test]
150 fn handle_command_error_failure() -> Result<()> {
151 let output = Output {
152 status: ExitStatus::from_raw(1),
153 stdout: Vec::new(),
154 stderr: Vec::from("Error message".as_bytes()),
155 };
156 assert!(matches!(
157 handle_command_error(&output, Error::BuildSpecError),
158 Err(Error::BuildSpecError(message))
159 if message == "Error message"
160 ));
161 Ok(())
162 }
163}