1use omp_core::Str;
13
14pub mod health;
15pub mod hello;
16pub mod tls;
17pub mod uds;
18
19pub use health::{HealthReporter, health_service};
20pub use hello::{HelloService, MIN_SCHEMA_REV, Peer, handshake};
21pub use tls::{TlsConfig, client_tls, server_tls};
22pub use uds::{Incoming, connect, listen};
23
24pub enum Error {
26 Io(std::io::Error),
28 Transport(tonic::transport::Error),
30 Rpc(tonic::Status),
32 Tls(Str),
34 SchemaTooOld {
36 server: u32,
38 client: u32,
40 },
41 SchemaUnsupported {
43 server_min: u32,
45 client: u32,
47 },
48 Unsupported(&'static str),
50}
51
52impl std::fmt::Debug for Error {
53 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 std::fmt::Display::fmt(self, formatter)
55 }
56}
57
58impl std::fmt::Display for Error {
59 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 match self {
61 Self::Io(error) => write!(formatter, "I/O error ({:?})", error.kind()),
62 Self::Transport(_) => formatter.write_str("transport error"),
63 Self::Rpc(status) => write!(formatter, "RPC error ({:?})", status.code()),
64 Self::Tls(_) => formatter.write_str("TLS configuration error"),
65 Self::SchemaTooOld { server, client } => write!(
66 formatter,
67 "server schema revision {server} is older than client revision {client}"
68 ),
69 Self::SchemaUnsupported { server_min, client } => write!(
70 formatter,
71 "client schema revision {client} is below server minimum {server_min}"
72 ),
73 Self::Unsupported(kind) => write!(formatter, "unsupported transport: {kind}"),
74 }
75 }
76}
77
78impl std::error::Error for Error {}
79
80impl From<std::io::Error> for Error {
81 fn from(error: std::io::Error) -> Self {
82 Self::Io(error)
83 }
84}
85
86impl From<tonic::transport::Error> for Error {
87 fn from(error: tonic::transport::Error) -> Self {
88 Self::Transport(error)
89 }
90}
91
92impl From<tonic::Status> for Error {
93 fn from(status: tonic::Status) -> Self {
94 Self::Rpc(status)
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::Error;
101
102 #[test]
103 fn observable_error_surfaces_discard_untrusted_diagnostics() {
104 const CANARY: &str = "canary-private-key-and-access-token";
105 let errors = [
106 Error::Io(std::io::Error::other(CANARY)),
107 Error::Rpc(tonic::Status::permission_denied(CANARY)),
108 Error::Tls(CANARY.into()),
109 ];
110
111 for error in errors {
112 assert!(!error.to_string().contains(CANARY));
113 assert!(!format!("{error:?}").contains(CANARY));
114 assert!(std::error::Error::source(&error).is_none());
115 }
116 }
117}