sc_rpc_spec_v2/bitswap/error.rs
1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Error helpers for the `bitswap` RPC module.
20
21use jsonrpsee::types::error::ErrorObject;
22
23/// Bitswap RPC errors.
24#[derive(Debug, thiserror::Error)]
25pub enum Error {
26 /// Invalid CID parameter.
27 #[error("Invalid CID: {0}")]
28 InvalidCid(String),
29 /// Transaction not found.
30 #[error("Transaction not found")]
31 NotFound,
32 /// Node is performing major sync.
33 #[error("Node is major syncing")]
34 MajorSyncing,
35 /// Internal error. Never emitted in practice
36 ///
37 /// Do not render the wrapped error to not expose the internal state to the remote caller.
38 #[error("Internal error")]
39 Internal(#[from] sp_blockchain::Error),
40}
41
42/// Bitswap JSON-RPC error categories, according to the spec.
43#[derive(Debug)]
44enum ErrorCode {
45 /// Invalid CID provided. Must never retry.
46 InvalidParams = -32602,
47 /// Must not retry.
48 Fail = -32810,
49 /// Can retry immediately, but rate limiting is encouraged.
50 _FailRetry = -32811,
51 /// Can retry with a backoff of 1-5 seconds.
52 FailRetryBackoff = -32812,
53}
54
55#[derive(serde::Serialize)]
56struct ErrorData {
57 variant: &'static str,
58}
59
60impl From<Error> for ErrorObject<'static> {
61 fn from(e: Error) -> Self {
62 let msg = e.to_string();
63
64 match e {
65 Error::InvalidCid(_) => ErrorObject::owned(
66 ErrorCode::InvalidParams as i32,
67 msg,
68 Some(ErrorData { variant: "InvalidCid" }),
69 ),
70 Error::NotFound => ErrorObject::owned(
71 ErrorCode::Fail as i32,
72 msg,
73 Some(ErrorData { variant: "NotFound" }),
74 ),
75 Error::MajorSyncing => ErrorObject::owned(
76 ErrorCode::FailRetryBackoff as i32,
77 msg,
78 Some(ErrorData { variant: "MajorSyncing" }),
79 ),
80 Error::Internal(_) => {
81 // This error is never emitted in practice and is only needed to cover all
82 // compile-type variants that `BlockBackend::indexed_transaction` returns.
83 // It is unclear what error category to use in case of internal errors, let's use
84 // `FAIL_RETRY_BACKOFF`.
85 ErrorObject::owned(
86 ErrorCode::FailRetryBackoff as i32,
87 msg,
88 Some(ErrorData { variant: "Internal" }),
89 )
90 },
91 }
92 }
93}