Skip to main content

pop_chains/
errors.rs

1// SPDX-License-Identifier: GPL-3.0
2
3use thiserror::Error;
4use zombienet_sdk::OrchestratorError;
5
6/// Represents the various errors that can occur in the crate.
7#[derive(Error, Debug)]
8pub enum Error {
9	/// The operation has been aborted due to an existing target directory.
10	#[error("User aborted due to existing target directory.")]
11	Aborted,
12	/// An error occurred.
13	#[error("Anyhow error: {0}")]
14	AnyhowError(#[from] anyhow::Error),
15	/// An error occurred while generating the chain specification.
16	#[error("Failed to build the chain spec: {0}")]
17	BuildSpecError(String),
18	/// An error occurred while running benchmarking.
19	#[error("Failed to run benchmarking: {0}")]
20	BenchmarkingError(String),
21	/// An error occurred while decoding the call data.
22	#[error("Failed to decode call data: {0}")]
23	CallDataDecodingError(String),
24	/// An error occurred while encoding the call data.
25	#[error("Failed to encode call data: {0}")]
26	CallDataEncodingError(String),
27	/// An error occurred.
28	#[error("{0}")]
29	CommonError(#[from] pop_common::Error),
30	/// An error occurred while attempting to establish a connection to the endpoint.
31	#[error("Failed to establish a connection to: {0}")]
32	ConnectionFailure(String),
33	/// A configuration error occurred.
34	#[error("Configuration error: {0}")]
35	Config(String),
36	/// The current directory could not be accessed.
37	#[error("Failed to access the current directory")]
38	CurrentDirAccess,
39	/// The endowment value could not be parsed.
40	#[error("Failed to parse the endowment value")]
41	EndowmentError,
42	/// The specified event was not found.
43	#[error("Event {0} not found.")]
44	EventNotFound(String),
45	/// An error occurred during the submission of an extrinsic.
46	#[error("Extrinsic submission error: {0}")]
47	ExtrinsicSubmissionError(String),
48	/// The callable item is not supported.
49	#[error("The callable item is not supported")]
50	CallableNotSupported,
51	/// Function not found.
52	#[error("Function not found: {0}")]
53	FunctionNotFound(String),
54	/// An error occurred while working with the genesis builder.
55	#[error("Genesis builder error: {0}")]
56	GenesisBuilderError(String),
57	/// Failed to retrieve the image tag.
58	#[error("Failed to retrieve image tag.")]
59	ImageTagRetrievalFailed,
60	/// An IO error occurred.
61	#[error("IO error: {0}")]
62	IO(#[from] std::io::Error),
63	/// A JSON error occurred.
64	#[error("JSON error: {0}")]
65	JsonError(#[from] serde_json::Error),
66	/// An error occurred while parsing metadata of a parameter.
67	#[error("Error parsing metadata for parameter: {0}")]
68	MetadataParsingError(String),
69	/// A binary is missing.
70	#[error("Missing binary: {0}")]
71	MissingBinary(String),
72	/// A chain spec is missing.
73	#[error("Missing chain spec file at: {0}")]
74	MissingChainSpec(String),
75	/// A required command does not exist.
76	#[error("Command {command} doesn't exist in binary {binary}")]
77	MissingCommand {
78		/// The required command.
79		command: String,
80		/// The binary used.
81		binary: String,
82	},
83	/// A network configuration error occurred.
84	#[error("Configuration error: {0:?}")]
85	NetworkConfigurationError(Vec<anyhow::Error>),
86	/// An orchestrator error occurred.
87	#[error("Orchestrator error: {0}")]
88	OrchestratorError(#[from] OrchestratorError),
89	/// The attempt to create a pallet directory failed.
90	#[error("Failed to create pallet directory")]
91	PalletDirCreation,
92	/// The specified pallet could not be found.
93	#[error("Failed to find the pallet: {0}")]
94	PalletNotFound(String),
95	/// An error occurred while processing the arguments provided by the user.
96	#[error("Failed to process the arguments provided by the user.")]
97	ParamProcessingError,
98	/// An error occurred while parsing the arguments provided by the user.
99	#[error("Failed to parse the arguments provided by the user: {0}")]
100	ParamParsingError(String),
101	/// The path is invalid.
102	#[error("Invalid path")]
103	PathError,
104	/// Failed to execute `rustfmt`.
105	#[error("Failed to execute rustfmt")]
106	RustfmtError(std::io::Error),
107	/// The specified runtime could not be found.
108	#[error("Failed to find the runtime {0}")]
109	RuntimeNotFound(String),
110	/// An error occurred sourcing a binary.
111	#[error("Template error: {0}")]
112	SourcingError(#[from] pop_common::sourcing::Error),
113	/// An error occurred whilst interacting with a chain using `subxt`.
114	#[error("Subxt error: {0}")]
115	SubXtError(#[from] Box<subxt::Error>),
116	/// A TOML error occurred.
117	#[error("Toml error: {0}")]
118	TomlError(#[from] toml_edit::de::Error),
119	/// An error occurred while testing with try-runtime.
120	#[error("Failed to test with try-runtime: {0}")]
121	TryRuntimeError(String),
122	/// The command is not supported.
123	#[error("Unsupported command: {0}")]
124	UnsupportedCommand(String),
125	/// The workspace could not be located.
126	#[error("Failed to locate the workspace")]
127	WorkspaceLocate,
128}
129
130// Handles command execution errors by extracting and returning the stderr message using the
131// provided error constructor.
132pub(crate) fn handle_command_error<F>(
133	output: &std::process::Output,
134	custom_error: F,
135) -> Result<(), Error>
136where
137	F: FnOnce(String) -> Error,
138{
139	if !output.status.success() {
140		let stderr_msg = String::from_utf8_lossy(&output.stderr);
141		return Err(custom_error(stderr_msg.to_string()));
142	}
143	Ok(())
144}
145
146#[cfg(test)]
147mod tests {
148	use super::*;
149	use anyhow::Result;
150	use std::{
151		os::unix::process::ExitStatusExt,
152		process::{ExitStatus, Output},
153	};
154
155	#[test]
156	fn handle_command_error_failure() -> Result<()> {
157		let output = Output {
158			status: ExitStatus::from_raw(1),
159			stdout: Vec::new(),
160			stderr: Vec::from("Error message".as_bytes()),
161		};
162		assert!(matches!(
163			handle_command_error(&output, Error::BuildSpecError),
164			Err(Error::BuildSpecError(message))
165			if message == "Error message"
166		));
167		Ok(())
168	}
169}