• 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 = "prost-codec")]
9 use prost::DecodeError;
10 #[cfg(feature = "protobuf-codec")]
11 use protobuf::ProtobufError;
12 
13 /// Errors generated from this library.
14 #[derive(Debug)]
15 pub enum Error {
16     /// Codec error.
17     Codec(Box<dyn error::Error + Send + Sync>),
18     /// Failed to start an internal async call.
19     CallFailure(grpc_call_error),
20     /// Rpc request fail.
21     RpcFailure(RpcStatus),
22     /// Try to write to a finished rpc call.
23     RpcFinished(Option<RpcStatus>),
24     /// Remote is stopped.
25     RemoteStopped,
26     /// Failed to shutdown.
27     ShutdownFailed,
28     /// Failed to bind.
29     BindFail(String, u16),
30     /// gRPC completion queue is shutdown.
31     QueueShutdown,
32     /// Failed to create Google default credentials.
33     GoogleAuthenticationFailed,
34     /// Invalid format of metadata.
35     InvalidMetadata(String),
36 }
37 
38 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result39     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
40         match self {
41             Error::RpcFailure(RpcStatus { status, details }) => match details {
42                 Some(details) => write!(fmt, "RpcFailure: {} {}", status, details),
43                 None => write!(fmt, "RpcFailure: {}", status),
44             },
45             other_error => write!(fmt, "{:?}", other_error),
46         }
47     }
48 }
49 
50 impl error::Error for Error {
source(&self) -> Option<&(dyn error::Error + 'static)>51     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
52         match *self {
53             Error::Codec(ref e) => Some(e.as_ref()),
54             _ => None,
55         }
56     }
57 }
58 
59 #[cfg(feature = "protobuf-codec")]
60 impl From<ProtobufError> for Error {
from(e: ProtobufError) -> Error61     fn from(e: ProtobufError) -> Error {
62         Error::Codec(Box::new(e))
63     }
64 }
65 
66 #[cfg(feature = "prost-codec")]
67 impl From<DecodeError> for Error {
from(e: DecodeError) -> Error68     fn from(e: DecodeError) -> Error {
69         Error::Codec(Box::new(e))
70     }
71 }
72 
73 /// Type alias to use this library's [`Error`] type in a `Result`.
74 pub type Result<T> = result::Result<T, Error>;
75 
76 #[cfg(all(test, feature = "protobuf-codec"))]
77 mod tests {
78     use std::error::Error as StdError;
79 
80     use protobuf::error::WireError;
81     use protobuf::ProtobufError;
82 
83     use super::Error;
84 
85     #[test]
test_convert()86     fn test_convert() {
87         let error = ProtobufError::WireError(WireError::UnexpectedEof);
88         let e: Error = error.into();
89         assert_eq!(e.to_string(), "Codec(WireError(UnexpectedEof))");
90         assert!(e.source().is_some());
91     }
92 }
93