opendal/services/gdrive/
error.rs1use http::Response;
19use http::StatusCode;
20use serde::Deserialize;
21
22use crate::raw::*;
23use crate::*;
24
25#[derive(Default, Debug, Deserialize)]
26struct GdriveError {
27 error: GdriveInnerError,
28}
29
30#[derive(Default, Debug, Deserialize)]
31struct GdriveInnerError {
32 message: String,
33}
34
35pub(super) fn parse_error(resp: Response<Buffer>) -> Error {
37 let (parts, body) = resp.into_parts();
38 let bs = body.to_bytes();
39
40 let (mut kind, mut retryable) = match parts.status {
41 StatusCode::NOT_FOUND => (ErrorKind::NotFound, false),
42 StatusCode::FORBIDDEN => (ErrorKind::PermissionDenied, false),
43 StatusCode::INTERNAL_SERVER_ERROR
44 | StatusCode::BAD_GATEWAY
45 | StatusCode::SERVICE_UNAVAILABLE
46 | StatusCode::GATEWAY_TIMEOUT
47 | StatusCode::METHOD_NOT_ALLOWED => (ErrorKind::Unexpected, true),
49 _ => (ErrorKind::Unexpected, false),
50 };
51
52 let (message, gdrive_err) = serde_json::from_slice::<GdriveError>(bs.as_ref())
53 .map(|gdrive_err| (format!("{gdrive_err:?}"), Some(gdrive_err)))
54 .unwrap_or_else(|_| (String::from_utf8_lossy(&bs).into_owned(), None));
55
56 if let Some(gdrive_err) = gdrive_err {
57 (kind, retryable) =
58 parse_gdrive_error_code(gdrive_err.error.message.as_str()).unwrap_or((kind, retryable));
59 }
60
61 let mut err = Error::new(kind, message);
62
63 err = with_error_response_context(err, parts);
64
65 if retryable {
66 err = err.set_temporary();
67 }
68
69 err
70}
71
72pub fn parse_gdrive_error_code(message: &str) -> Option<(ErrorKind, bool)> {
73 match message {
74 "User rate limit exceeded." => Some((ErrorKind::RateLimited, true)),
78 _ => None,
79 }
80}