• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2 
3 use std::{error, fmt, result};
4 
5 use crate::call::RpcStatus;
6 use crate::grpc_sys::grpc_call_error;
7 
8 #[cfg(feature = "protobuf-codec")]
9 use protobuf::ProtobufError;
10 
11 /// Errors generated from this library.
12 #[derive(Debug)]
13 pub enum Error {
14     /// Codec error.
15     Codec(Box<dyn error::Error + Send + Sync>),
16     /// Failed to start an internal async call.
17     CallFailure(grpc_call_error),
18     /// Rpc request fail.
19     RpcFailure(RpcStatus),
20     /// Try to write to a finished rpc call.
21     RpcFinished(Option<RpcStatus>),
22     /// Remote is stopped.
23     RemoteStopped,
24     /// Failed to shutdown.
25     ShutdownFailed,
26     /// Failed to bind.
27     BindFail(String, u16),
28     /// gRPC completion queue is shutdown.
29     QueueShutdown,
30     /// Failed to create Google default credentials.
31     GoogleAuthenticationFailed,
32     /// Invalid format of metadata.
33     InvalidMetadata(String),
34 }
35 
36 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result37     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
38         match self {
39             Error::RpcFailure(s) => {
40                 if s.message().is_empty() {
41                     write!(fmt, "RpcFailure: {}", s.code())
42                 } else {
43                     write!(fmt, "RpcFailure: {} {}", s.code(), s.message())
44                 }
45             }
46             other_error => write!(fmt, "{:?}", other_error),
47         }
48     }
49 }
50 
51 impl error::Error for Error {
source(&self) -> Option<&(dyn error::Error + 'static)>52     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
53         match *self {
54             Error::Codec(ref e) => Some(e.as_ref()),
55             _ => None,
56         }
57     }
58 }
59 
60 #[cfg(feature = "protobuf-codec")]
61 impl From<ProtobufError> for Error {
from(e: ProtobufError) -> Error62     fn from(e: ProtobufError) -> Error {
63         Error::Codec(Box::new(e))
64     }
65 }
66 
67 #[cfg(feature = "prost-codec")]
68 impl From<prost::DecodeError> for Error {
from(e: prost::DecodeError) -> Error69     fn from(e: prost::DecodeError) -> Error {
70         Error::Codec(Box::new(e))
71     }
72 }
73 
74 #[cfg(feature = "prost-codec")]
75 impl From<prost::EncodeError> for Error {
from(e: prost::EncodeError) -> Error76     fn from(e: prost::EncodeError) -> Error {
77         Error::Codec(Box::new(e))
78     }
79 }
80 
81 /// Type alias to use this library's [`Error`] type in a `Result`.
82 pub type Result<T> = result::Result<T, Error>;
83 
84 #[cfg(all(test, feature = "protobuf-codec"))]
85 mod tests {
86     use std::error::Error as StdError;
87 
88     use protobuf::error::WireError;
89     use protobuf::ProtobufError;
90 
91     use super::Error;
92 
93     #[test]
test_convert()94     fn test_convert() {
95         let error = ProtobufError::WireError(WireError::UnexpectedEof);
96         let e: Error = error.into();
97         assert_eq!(e.to_string(), "Codec(WireError(UnexpectedEof))");
98         assert!(e.source().is_some());
99     }
100 }
101