1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
//! Roads API error types and error messages.
// -----------------------------------------------------------------------------
use crate::roads::status::Status;
use miette::Diagnostic;
use thiserror::Error;
// -----------------------------------------------------------------------------
//
/// Errors that may be produced by the Google Maps Roads API client.
#[derive(Debug, Diagnostic, Error)]
#[diagnostic(code(google_maps::roads::error), url(docsrs))]
pub enum Error {
/// Google Maps Roads API server generated an error. See the `Status`
/// enum for more information.
GoogleMapsService(Status, Option<String>),
/// The HTTP request was unsuccessful.
HttpUnsuccessful(String),
/// API client library attempted to parse a string that contained an invalid
/// status code. See `google_maps\src\time_zone\response\status.rs` for more
/// information.
InvalidStatusCode(String),
/// The query string must be built before the request may be sent to the
/// Google Maps Roads API server.
QueryNotBuilt,
/// The dependency library Reqwest generated an error.
#[cfg(feature = "enable-reqwest")]
Reqwest(crate::ReqError),
/// The dependency library Reqwest generated an error. The error could
/// not be passed normally so a `String` representation is passed instead.
#[cfg(feature = "enable-reqwest")]
ReqwestMessage(String),
/// The dependency library Serde JSON generated an error.
SerdeJson(serde_json::error::Error),
} // enum
// -----------------------------------------------------------------------------
impl std::fmt::Display for Error {
/// This trait converts the error code into a format that may be presented
/// to the user.
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::GoogleMapsService(status, error_message) => match error_message {
// If the Google Maps Roads API server generated an error
// message, return that:
Some(error_message) => write!(f, "Google Maps Roads API service: {error_message}"),
// If the Google Maps Roads API server did not generate an
// error message, return a generic message derived from the
// response status:
None => match status {
Status::InvalidArgument => write!(f, "Google Maps Roads API service: \
Invalid argument. \
1. Your API key is not valid or was not included in the request. \
or, 2. Your request contained invalid arguments."),
Status::PermissionDenied => write!(f, "Google Maps Roads API service: \
Permission Denied. \
1. API key missing or invalid. \
2. Billing not enabled. \
3. Self-imposed usage cap exceeded. \
or, 4. Method of payment no longer valid."),
Status::NotFound => write!(f, "Google Maps Roads API service: \
Not found. \
Ensure that you are sending requests \
to `https://roads.googleapis.com/` and not \
`http://roads.googleapis.com/`."),
Status::ResourceExhausted => write!(f, "Google Maps Roads API service: \
Not found. \
You have exceeded the request limit that you configured \
in the Google Cloud Platform Console."),
} // match
}, // match
Self::HttpUnsuccessful(status) => write!(f,
"Google Maps Roads API client: \
Could not successfully query the Google Cloud Platform service. \
The service last responded with a `{status}` status."),
Self::InvalidStatusCode(status_code) => write!(f, "Google Maps Roads API client: \
`{status_code}` is not a valid status code. \
Valid codes are `INVALID_ARGUMENT`, `PERMISSION_DENIED`, \
`NOT_FOUND`, and `RESOURCE_EXHAUSTED`."),
Self::QueryNotBuilt => write!(f, "Google Maps Roads API client library: \
The query string must be built before the request may be sent to the Google Cloud Maps Platform. \
Ensure the build() method is called before run()."),
#[cfg(feature = "enable-reqwest")]
Self::Reqwest(error) => write!(f, "Google Maps Roads API client in the Reqwest library: {error}"),
#[cfg(feature = "enable-reqwest")]
Self::ReqwestMessage(error) => write!(f, "Google Maps Geocoding API client in the Reqwest library: {error}"),
Self::SerdeJson(error) => write!(f, "Google Maps Roads API client in the Serde JSON library: {error}"),
} // match
} // fn
} // impl
// -----------------------------------------------------------------------------
#[cfg(feature = "enable-reqwest")]
impl From<reqwest::Error> for Error {
/// This trait converts from an Reqwest error type (`reqwest::Error`) into a
/// Google Maps Roads API error type
/// (`google_maps::time_zone::error::Error`) by wrapping it inside. This
/// function is required to use the `?` operator.
fn from(error: reqwest::Error) -> Self {
Self::Reqwest(crate::ReqError::from(error))
} // fn
} // impl
// -----------------------------------------------------------------------------
impl From<serde_json::error::Error> for Error {
/// This trait converts from an Serde JSON (`serde_json::error::Error`)
/// error type into a Google Maps Roads API error type
/// (`google_maps::time_zone::error::Error`) by wrapping it inside. This
/// function is required to use the `?` operator.
fn from(error: serde_json::error::Error) -> Self {
Self::SerdeJson(error)
} // fn
} // impl