referrerpolicy=no-referrer-when-downgrade

polkadot_availability_distribution/
error.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
18//! Error handling related code and Error/Result definitions.
19
20use fatality::Nested;
21use polkadot_node_network_protocol::request_response::outgoing::RequestError;
22use polkadot_primitives::SessionIndex;
23
24use futures::channel::oneshot;
25
26use polkadot_node_subsystem::{ChainApiError, RuntimeApiError, SubsystemError};
27use polkadot_node_subsystem_util::runtime;
28
29use crate::LOG_TARGET;
30
31#[allow(missing_docs)]
32#[fatality::fatality(splitable)]
33pub enum Error {
34	#[fatal]
35	#[error("Spawning subsystem task failed: {0}")]
36	SpawnTask(#[source] SubsystemError),
37
38	#[fatal]
39	#[error("Erasure chunk requester stream exhausted")]
40	RequesterExhausted,
41
42	#[fatal]
43	#[error("Receive channel closed: {0}")]
44	IncomingMessageChannel(#[source] SubsystemError),
45
46	#[fatal(forward)]
47	#[error("Error while accessing runtime information: {0}")]
48	Runtime(#[from] runtime::Error),
49
50	#[fatal]
51	#[error("Oneshot for receiving response from Chain API got cancelled")]
52	ChainApiSenderDropped(#[from] oneshot::Canceled),
53
54	#[fatal]
55	#[error("Retrieving response from Chain API unexpectedly failed with error: {0}")]
56	ChainApi(#[from] ChainApiError),
57
58	#[error("Failed to get node features from the runtime")]
59	FailedNodeFeatures(#[source] RuntimeApiError),
60
61	// av-store will drop the sender on any error that happens.
62	#[error("Response channel to obtain chunk failed")]
63	QueryChunkResponseChannel(#[source] oneshot::Canceled),
64
65	// av-store will drop the sender on any error that happens.
66	#[error("Response channel to obtain available data failed")]
67	QueryAvailableDataResponseChannel(#[source] oneshot::Canceled),
68
69	// We tried accessing a session that was not cached.
70	#[error("Session {missing_session} is not cached, cached sessions: {available_sessions:?}.")]
71	NoSuchCachedSession { available_sessions: Vec<SessionIndex>, missing_session: SessionIndex },
72
73	// Sending request response failed (Can happen on timeouts for example).
74	#[error("Sending a request's response failed.")]
75	SendResponse,
76
77	#[error("FetchPoV request error: {0}")]
78	FetchPoV(#[source] RequestError),
79
80	#[error("Fetched PoV does not match expected hash")]
81	UnexpectedPoV,
82
83	#[error("Remote responded with `NoSuchPoV`")]
84	NoSuchPoV,
85
86	#[error("Given validator index could not be found in current session")]
87	InvalidValidatorIndex,
88
89	#[error("Erasure coding error: {0}")]
90	ErasureCoding(#[from] polkadot_erasure_coding::Error),
91}
92
93/// General result abbreviation type alias.
94pub type Result<T> = std::result::Result<T, Error>;
95
96/// Utility for eating top level errors and log them.
97///
98/// We basically always want to try and continue on error. This utility function is meant to
99/// consume top-level errors by simply logging them
100pub fn log_error(
101	result: Result<()>,
102	ctx: &'static str,
103	warn_freq: &mut gum::Freq,
104) -> std::result::Result<(), FatalError> {
105	match result.into_nested()? {
106		Ok(()) => Ok(()),
107		Err(jfyi) => {
108			match jfyi {
109				JfyiError::UnexpectedPoV |
110				JfyiError::InvalidValidatorIndex |
111				JfyiError::NoSuchCachedSession { .. } |
112				JfyiError::QueryAvailableDataResponseChannel(_) |
113				JfyiError::QueryChunkResponseChannel(_) |
114				JfyiError::FailedNodeFeatures(_) |
115				JfyiError::ErasureCoding(_) => gum::warn!(target: LOG_TARGET, error = %jfyi, ctx),
116				JfyiError::FetchPoV(_) |
117				JfyiError::SendResponse |
118				JfyiError::NoSuchPoV |
119				JfyiError::Runtime(_) =>
120					gum::warn_if_frequent!(freq: warn_freq, max_rate: gum::Times::PerHour(100), target: LOG_TARGET, error = ?jfyi, ctx),
121			}
122			Ok(())
123		},
124	}
125}