polkadot_node_subsystem_types/
errors.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Error types for the subsystem requests.
18
19use crate::JaegerError;
20use ::orchestra::OrchestraError as OverseerError;
21use fatality::fatality;
22
23/// A description of an error causing the runtime API request to be unservable.
24#[derive(thiserror::Error, Debug, Clone)]
25pub enum RuntimeApiError {
26	/// The runtime API cannot be executed due to a runtime error.
27	#[error("The runtime API '{runtime_api_name}' cannot be executed: {source}")]
28	Execution {
29		/// The runtime API being called
30		runtime_api_name: &'static str,
31		/// The wrapped error. Marked as source for tracking the error chain.
32		#[source]
33		source: std::sync::Arc<dyn 'static + std::error::Error + Send + Sync>,
34	},
35
36	/// The runtime API request in question cannot be executed because the runtime at the requested
37	/// relay-parent is an old version.
38	#[error("The API is not supported by the runtime at the relay-parent")]
39	NotSupported {
40		/// The runtime API being called
41		runtime_api_name: &'static str,
42	},
43}
44
45/// A description of an error causing the chain API request to be unservable.
46#[derive(Debug, Clone)]
47pub struct ChainApiError {
48	msg: String,
49}
50
51impl From<&str> for ChainApiError {
52	fn from(s: &str) -> Self {
53		s.to_owned().into()
54	}
55}
56
57impl From<String> for ChainApiError {
58	fn from(msg: String) -> Self {
59		Self { msg }
60	}
61}
62
63impl core::fmt::Display for ChainApiError {
64	fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
65		write!(f, "{}", self.msg)
66	}
67}
68
69impl std::error::Error for ChainApiError {}
70
71/// An error that may happen during Availability Recovery process.
72#[derive(PartialEq, Clone)]
73#[fatality(splitable)]
74#[allow(missing_docs)]
75pub enum RecoveryError {
76	#[error("Invalid data")]
77	Invalid,
78
79	#[error("Data is unavailable")]
80	Unavailable,
81
82	#[fatal]
83	#[error("Erasure task channel closed")]
84	ChannelClosed,
85}
86
87/// An error type that describes faults that may happen
88///
89/// These are:
90///   * Channels being closed
91///   * Subsystems dying when they are not expected to
92///   * Subsystems not dying when they are told to die
93///   * etc.
94#[derive(thiserror::Error, Debug)]
95#[allow(missing_docs)]
96pub enum SubsystemError {
97	#[error(transparent)]
98	NotifyCancellation(#[from] futures::channel::oneshot::Canceled),
99
100	#[error(transparent)]
101	QueueError(#[from] futures::channel::mpsc::SendError),
102
103	#[error(transparent)]
104	Io(#[from] std::io::Error),
105
106	#[error(transparent)]
107	Infallible(#[from] std::convert::Infallible),
108
109	#[error(transparent)]
110	Prometheus(#[from] prometheus_endpoint::PrometheusError),
111
112	#[error(transparent)]
113	Jaeger(#[from] JaegerError),
114
115	#[error("Failed to {0}")]
116	Context(String),
117
118	#[error("Subsystem stalled: {0}")]
119	SubsystemStalled(&'static str),
120
121	/// Generated by the `#[overseer(..)]` proc-macro
122	#[error(transparent)]
123	Generated(#[from] OverseerError),
124
125	/// Per origin (or subsystem) annotations to wrap an error.
126	#[error("Error originated in {origin}")]
127	FromOrigin {
128		/// An additional annotation tag for the origin of `source`.
129		origin: &'static str,
130		/// The wrapped error. Marked as source for tracking the error chain.
131		#[source]
132		source: Box<dyn 'static + std::error::Error + Send + Sync>,
133	},
134}
135
136// impl AnnotateErrorOrigin for SubsystemError {
137// 	fn with_origin(self, origin: &'static str) -> Self {
138// 		Self::FromOrigin {
139// 			origin,
140// 			source: Box::new(self),
141// 		}
142// 	}
143// }
144
145impl SubsystemError {
146	/// Adds a `str` as `origin` to the given error `err`.
147	pub fn with_origin<E: 'static + Send + Sync + std::error::Error>(
148		origin: &'static str,
149		err: E,
150	) -> Self {
151		Self::FromOrigin { origin, source: Box::new(err) }
152	}
153}
154
155/// Ease the use of subsystem errors.
156pub type SubsystemResult<T> = Result<T, self::SubsystemError>;