pop_parachains/
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 dispatchable function is not supported.
49	#[error("The dispatchable function is not supported")]
50	FunctionNotSupported,
51	/// An error occurred while working with the genesis builder.
52	#[error("Genesis builder error: {0}")]
53	GenesisBuilderError(String),
54	/// Failed to retrieve the image tag.
55	#[error("Failed to retrieve image tag.")]
56	ImageTagRetrievalFailed,
57	/// An IO error occurred.
58	#[error("IO error: {0}")]
59	IO(#[from] std::io::Error),
60	/// A JSON error occurred.
61	#[error("JSON error: {0}")]
62	JsonError(#[from] serde_json::Error),
63	/// An error occurred while parsing metadata of a parameter.
64	#[error("Error parsing metadata for parameter {0}")]
65	MetadataParsingError(String),
66	/// A binary is missing.
67	#[error("Missing binary: {0}")]
68	MissingBinary(String),
69	/// A chain spec is missing.
70	#[error("Missing chain spec file at: {0}")]
71	MissingChainSpec(String),
72	/// A required command does not exist.
73	#[error("Command {command} doesn't exist in binary {binary}")]
74	MissingCommand {
75		/// The required command.
76		command: String,
77		/// The binary used.
78		binary: String,
79	},
80	/// An orchestrator error occurred.
81	#[error("Orchestrator error: {0}")]
82	OrchestratorError(#[from] OrchestratorError),
83	/// The attempt to create a pallet directory failed.
84	#[error("Failed to create pallet directory")]
85	PalletDirCreation,
86	/// The specified pallet could not be found.
87	#[error("Failed to find the pallet {0}")]
88	PalletNotFound(String),
89	/// An error occurred while processing the arguments provided by the user.
90	#[error("Failed to process the arguments provided by the user.")]
91	ParamProcessingError,
92	/// An error occurred while parsing the arguments provided by the user.
93	#[error("Failed to parse the arguments provided by the user: {0}")]
94	ParamParsingError(String),
95	/// The path is invalid.
96	#[error("Invalid path")]
97	PathError,
98	/// Failed to execute `rustfmt`.
99	#[error("Failed to execute rustfmt")]
100	RustfmtError(std::io::Error),
101	/// The specified runtime could not be found.
102	#[error("Failed to find the runtime {0}")]
103	RuntimeNotFound(String),
104	/// An error occurred sourcing a binary.
105	#[error("Template error: {0}")]
106	SourcingError(#[from] pop_common::sourcing::Error),
107	/// An error occurred whilst interacting with a chain using `subxt`.
108	#[error("Subxt error: {0}")]
109	SubXtError(#[from] subxt::Error),
110	/// A TOML error occurred.
111	#[error("Toml error: {0}")]
112	TomlError(#[from] toml_edit::de::Error),
113	/// An error occurred while testing with try-runtime.
114	#[error("Failed to test with try-runtime: {0}")]
115	TryRuntimeError(String),
116	/// The command is not supported.
117	#[error("Unsupported command: {0}")]
118	UnsupportedCommand(String),
119	/// The workspace could not be located.
120	#[error("Failed to locate the workspace")]
121	WorkspaceLocate,
122}
123
124// Handles command execution errors by extracting and returning the stderr message using the
125// provided error constructor.
126pub(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}