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
use std::error::Error;
use std::fmt;
/// An error response returned from Google Cloud Storage.
///
/// See the [`HTTP status and error codes for JSON`][1] documentation for more details.
///
/// [1]: https://cloud.google.com/storage/docs/json_api/v1/status-codes
#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ErrorResponse {
/// An HTTP status value, without the textual description.
///
/// Example values include: `400` (Bad Request), `401` (Unauthorized), and `404` (Not Found).
pub code: u16,
/// A container for the error details.
pub errors: Vec<ErrorResponseItem>,
/// Description of the error. Same as `errors.message`.
pub message: String,
}
impl ErrorResponse {
/// Returns `true` if the error is retriable according to the [GCS documentation][1].
///
/// [1]: https://cloud.google.com/storage/docs/retry-strategy#retryable
pub fn is_retriable(&self) -> bool {
matches!(self.code, 408 | 429 | 500..=599)
}
}
impl fmt::Display for ErrorResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.message.fmt(f)
}
}
impl Error for ErrorResponse {}
#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ErrorResponseItem {
/// The scope of the error. Example values include: `global` and `push`.
pub domain: String,
/// The specific item within the `locationType` that caused the error. For example, if you
/// specify an invalid value for a parameter, the `location` will be the name of the parameter.
///
/// Example values include: `Authorization`, `project`, and `projection`.
pub location: Option<String>,
/// The location or part of the request that caused the error. Use with `location` to pinpoint
/// the error. For example, if you specify an invalid value for a parameter, the `locationType`
/// will be `parameter` and the `location` will be the name of the parameter.
///
/// Example values include `header` and `parameter`.
pub location_type: Option<String>,
/// Description of the error.
///
/// Example values include `Invalid argument`, `Login required`, and
/// `Required parameter: project`.
pub message: String,
/// Example values include `invalid`, `invalidParameter`, and `required`.
pub reason: String,
}
impl fmt::Display for ErrorResponseItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.message.fmt(f)
}
}
/// The GCS error response JSON format contains an extra object level that is inconvenient to include in our
/// error.
#[derive(serde::Deserialize)]
pub(crate) struct ErrorWrapper {
pub(crate) error: ErrorResponse,
}