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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
//! Geocoding API error types and error messages.
// -----------------------------------------------------------------------------
use crate::geocoding::response::status::Status;
use miette::Diagnostic;
use thiserror::Error;
// -----------------------------------------------------------------------------
//
/// Errors that may be produced by the Google Maps Geocoding API client.
#[derive(Debug, Diagnostic, Error)]
#[diagnostic(code(google_maps::geocoding), url(docsrs))]
pub enum Error {
/// Forward geocoding requests (address to latlng) must specify an `address`
/// or at least one `component`.
AddressOrComponentsRequired,
/// Google Maps Geocoding 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
/// country code. See `google_maps\src\geocoding\forward\country.rs` for
/// more information.
InvalidCountryCode(String),
/// API client library attempted to parse a string that contained an invalid
/// location type code. See `google_maps\src\geocoding\location_types.rs`
/// for more information.
InvalidLocationTypeCode(String),
/// API client library attempted to parse a string that contained an invalid
/// status code. See `google_maps\src\geocoding\response\status.rs` for more
/// information.
InvalidStatusCode(String),
/// The query string must be built before the request may be sent to the
/// Google Maps Geocoding API server.
QueryNotBuilt,
/// The request must be validated before a query string may be built.
RequestNotValidated,
/// The dependency library Reqwest generated an error.
#[cfg(feature = "enable-reqwest")]
Reqwest(reqwest::Error),
/// 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 {
Error::AddressOrComponentsRequired => write!(f,
"Google Maps Geocoding API client: \
Forward geocoding requests must specify an `address` or at least one `component`. \
Ensure that the with_address() and/or with_component methods are being called before run()."),
Error::GoogleMapsService(status, error_message) => match error_message {
// If the Google Maps Geocoding API server generated an error
// message, return that:
Some(error_message) => write!(f, "Google Maps Geocoding API server: {error_message}"),
// If the Google Maps Geocoding API server did not generate an
// error message, return a generic message derived from the
// response status:
None => match status {
Status::InvalidRequest => write!(f, "Google Maps Geocoding API server: \
Invalid request. \
This may indicate that the query (address, components, or latlng) is missing, an invalid result type, or an invalid location type."),
Status::Ok => write!(f, "Google Maps Geocoding server: \
Ok. \
The request was successful."),
Status::OverDailyLimit => write!(f, "Google Maps Geocoding API server: \
Over daily limit. \
Usage cap has been exceeded, API key is invalid, billing has not been enabled, or method of payment is no longer valid."),
Status::OverQueryLimit => write!(f, "Google Maps Geocoding API server: \
Over query limit. \
Requestor has exceeded quota."),
Status::RequestDenied => write!(f, "Google Maps Geocoding API server: \
Request denied \
Service did not complete the request."),
Status::UnknownError => write!(f, "Google Maps Geocoding API server: \
Unknown error."),
Status::ZeroResults => write!(f, "Google Maps Geocoding API server: \
Zero results. \
This may occur if the geocoder was passed a non-existent address."),
} // match
}, // match
Error::HttpUnsuccessful(status) => write!(f,
"Google Maps Geocoding API client: \
Could not successfully query the Google Cloud Platform service. \
The service last responded with a `{status}` status."),
Error::InvalidCountryCode(country_code) => write!(f,
"Google Maps Geocoding API client: \
`{country_code}` is not a valid ISO 3166-1 Alpha-2 country code. \
Note that the country code must be in uppercase. \
For a list of country codes see \
https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes"),
Error::InvalidLocationTypeCode(location_type_code) => write!(f,
"Google Maps Geocoding API client: \
`{location_type_code}` is not a known location type code. \
Valid codes are `APPROXIMATE`, `GEOMETRIC_CENTER`, \
`RANGE_INTERPOLATED`, and `ROOFTOP`."),
Error::InvalidStatusCode(status_code) => write!(f,
"Google Maps Geocoding API client: \
`{status_code}` is not a valid status code. \
Valid codes are `INVALID_REQUEST`, `OK`, `OVER_DAILY_LIMIT`, \
`OVER_QUERY_LIMIT`, `REQUEST_DENIED`, `UNKNOWN_ERROR`, and \
`ZERO_RESULTS`."),
Error::QueryNotBuilt => write!(f,
"Google Maps Geocoding API client: \
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()."),
Error::RequestNotValidated => write!(f,
"Google Maps Geocoding API client: \
The request must be validated before a query string may be built. \
Ensure the validate() method is called before build()."),
#[cfg(feature = "enable-reqwest")]
Error::Reqwest(error) => write!(f, "Google Maps Geocoding API client in the Reqwest library: {error}"),
#[cfg(feature = "enable-reqwest")]
Error::ReqwestMessage(error) => write!(f, "Google Maps Geocoding API client in the Reqwest library: {error}"),
Error::SerdeJson(error) => write!(f, "Google Maps Geocoding 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 Geocoding API error type
/// (`google_maps::geocoding::error::Error`) by wrapping it inside. This
/// function is required to use the `?` operator.
fn from(error: reqwest::Error) -> Error {
Error::Reqwest(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 Geocoding API error type
/// (`google_maps::geocoding::error::Error`) by wrapping it inside. This
/// function is required to use the `?` operator.
fn from(error: serde_json::error::Error) -> Error {
Error::SerdeJson(error)
} // fn
} // impl