1use std::{convert::From, fmt};
2
3#[derive(Debug)]
5#[non_exhaustive]
6pub enum ErrorKind {
7 Http(reqwest::Error),
9 HttpStatus(reqwest::StatusCode),
11 CredentialsBuild(google_cloud_auth::build_errors::Error),
14 Credentials(google_cloud_auth::errors::CredentialsError),
18 TonicMetadata(tonic::metadata::errors::InvalidMetadataValue),
19 GrpcStatus(tonic::transport::Error),
20 UrlError(hyper::http::uri::InvalidUri),
21 InvalidApiUrl(String),
24 HeaderValue(hyper::header::InvalidHeaderValue),
27 IdTokenNeedsImpersonation(IdTokenUnsupportedCredentials),
31 InvalidImpersonationUrl(String),
34 CryptoProviderMissing,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47#[non_exhaustive]
48pub enum IdTokenUnsupportedCredentials {
49 AuthorizedUser,
52 ExternalAccount,
54 ExternalAccountAuthorizedUser,
58 GdchServiceAccount,
60}
61
62impl fmt::Display for IdTokenUnsupportedCredentials {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 match self {
65 Self::AuthorizedUser => write!(f, "authorized_user credentials"),
66 Self::ExternalAccount => write!(
67 f,
68 "external_account credentials without service_account_impersonation_url"
69 ),
70 Self::ExternalAccountAuthorizedUser => {
71 write!(f, "external_account_authorized_user credentials")
72 }
73 Self::GdchServiceAccount => write!(f, "gdch_service_account credentials"),
74 }
75 }
76}
77
78#[derive(Debug)]
80pub struct Error(Box<ErrorKind>);
81
82impl Error {
83 pub fn kind(&self) -> &ErrorKind {
85 &self.0
86 }
87
88 pub fn into_kind(self) -> ErrorKind {
90 *self.0
91 }
92}
93
94impl fmt::Display for Error {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 use ErrorKind::*;
97 match *self.0 {
98 Http(ref e) => write!(f, "http error: {}", e),
99 HttpStatus(ref s) => write!(f, "http status error: {}", s),
100 CredentialsBuild(ref e) => write!(f, "credentials build error: {}", e),
101 Credentials(ref e) => write!(f, "credentials error: {}", e),
102 GrpcStatus(ref e) => write!(f, "Tonic/gRPC error: {}", e),
103 TonicMetadata(ref e) => write!(f, "Tonic metadata error: {}", e),
104 UrlError(ref e) => write!(f, "Url error: {}", e),
105 InvalidApiUrl(ref e) => write!(f, "Invalid API URL: {}", e),
106 HeaderValue(ref e) => write!(f, "invalid header value: {}", e),
107 IdTokenNeedsImpersonation(ref credentials) => write!(
108 f,
109 "{} cannot mint an ID token; give a service account to impersonate",
110 credentials
111 ),
112 InvalidImpersonationUrl(ref url) => write!(
113 f,
114 "service_account_impersonation_url names no service account: {}",
115 url
116 ),
117 CryptoProviderMissing => write!(
118 f,
119 "the credentials sign with a private key and no rustls CryptoProvider is installed; \
120 install one with CryptoProvider::install_default or enable the auth-default-crypto feature"
121 ),
122 }
123 }
124}
125
126impl std::error::Error for Error {}
127
128impl From<reqwest::Error> for Error {
129 fn from(e: reqwest::Error) -> Self {
130 ErrorKind::Http(e).into()
131 }
132}
133
134impl From<google_cloud_auth::build_errors::Error> for Error {
135 fn from(e: google_cloud_auth::build_errors::Error) -> Self {
136 ErrorKind::CredentialsBuild(e).into()
137 }
138}
139
140impl From<google_cloud_auth::errors::CredentialsError> for Error {
141 fn from(e: google_cloud_auth::errors::CredentialsError) -> Self {
142 ErrorKind::Credentials(e).into()
143 }
144}
145
146impl From<ErrorKind> for Error {
147 fn from(k: ErrorKind) -> Self {
148 Error(Box::new(k))
149 }
150}
151
152impl From<tonic::transport::Error> for Error {
153 fn from(e: tonic::transport::Error) -> Self {
154 ErrorKind::GrpcStatus(e).into()
155 }
156}
157
158impl From<tonic::metadata::errors::InvalidMetadataValue> for Error {
159 fn from(e: tonic::metadata::errors::InvalidMetadataValue) -> Self {
160 ErrorKind::TonicMetadata(e).into()
161 }
162}
163
164impl From<hyper::http::uri::InvalidUri> for Error {
165 fn from(e: hyper::http::uri::InvalidUri) -> Self {
166 ErrorKind::UrlError(e).into()
167 }
168}
169
170impl From<hyper::header::InvalidHeaderValue> for Error {
171 fn from(e: hyper::header::InvalidHeaderValue) -> Self {
172 ErrorKind::HeaderValue(e).into()
173 }
174}
175
176pub type Result<T> = std::result::Result<T, Error>;