1use std::error::Error;
4
5use displaydoc::Display;
6
7use massa_consensus_exports::error::ConsensusError;
8use massa_execution_exports::ExecutionError;
9use massa_hash::MassaHashError;
10use massa_models::error::ModelsError;
11use massa_protocol_exports::ProtocolError;
12use massa_signature::MassaSignatureError;
13use massa_time::TimeError;
14use massa_versioning::versioning_factory::FactoryError;
15use massa_wallet::WalletError;
16use tracing::error;
17
18#[non_exhaustive]
20#[derive(Display, thiserror::Error, Debug)]
21pub enum GrpcError {
22 MassaHashError(#[from] MassaHashError),
24 MassaSignatureError(#[from] MassaSignatureError),
26 ConsensusError(#[from] ConsensusError),
28 ExecutionError(#[from] ExecutionError),
30 ProtocolError(#[from] ProtocolError),
32 ReflectionError(#[from] tonic_reflection::server::Error),
34 ModelsError(#[from] ModelsError),
36 TimeError(#[from] TimeError),
38 FactoryError(#[from] FactoryError),
40 WalletError(#[from] WalletError),
42 InternalServerError(String),
44 InvalidArgument(String),
46 ConfigError(String),
48 Unimplemented(String),
50}
51
52impl From<GrpcError> for tonic::Status {
53 fn from(error: GrpcError) -> Self {
54 error!("{}", error);
55 match error {
56 GrpcError::MassaHashError(e) => tonic::Status::internal(e.to_string()),
57 GrpcError::MassaSignatureError(e) => tonic::Status::internal(e.to_string()),
58 GrpcError::ConsensusError(e) => tonic::Status::internal(e.to_string()),
59 GrpcError::ExecutionError(e) => tonic::Status::internal(e.to_string()),
60 GrpcError::ProtocolError(e) => tonic::Status::internal(e.to_string()),
61 GrpcError::ModelsError(e) => tonic::Status::internal(e.to_string()),
62 GrpcError::TimeError(e) => tonic::Status::internal(e.to_string()),
63 GrpcError::FactoryError(e) => tonic::Status::internal(e.to_string()),
64 GrpcError::WalletError(e) => tonic::Status::internal(e.to_string()),
65 GrpcError::InternalServerError(e) => tonic::Status::internal(e),
66 GrpcError::ReflectionError(e) => tonic::Status::internal(e.to_string()),
67 GrpcError::InvalidArgument(e) => tonic::Status::invalid_argument(e),
68 GrpcError::ConfigError(e) => tonic::Status::internal(e),
69 GrpcError::Unimplemented(e) => tonic::Status::unimplemented(e),
70 }
71 }
72}
73
74pub fn match_for_io_error(err_status: &tonic::Status) -> Option<&std::io::Error> {
76 let mut err: &(dyn Error + 'static) = err_status;
77
78 loop {
79 if let Some(io_err) = err.downcast_ref::<std::io::Error>() {
80 return Some(io_err);
81 }
82
83 if let Some(h2_err) = err.downcast_ref::<h2::Error>() {
86 if let Some(io_err) = h2_err.get_io() {
87 return Some(io_err);
88 }
89 }
90
91 err = err.source()?;
92 }
93}