aliyun_oss_rs/
error.rs

1#[cfg(feature = "async")]
2use crate::common::body_to_bytes;
3use bytes::Bytes;
4use http::StatusCode;
5#[cfg(feature = "async")]
6use hyper::{Response, body::Incoming};
7#[cfg(feature = "async")]
8use hyper_util::client::legacy::Error as HyperClientError;
9use serde_derive::Deserialize;
10#[cfg(feature = "sync")]
11use std::io::Read;
12use thiserror::Error;
13#[cfg(feature = "sync")]
14use ureq::{self, Body};
15
16#[derive(Error, Debug)]
17pub enum Error {
18    #[error("{0}")]
19    IoError(#[from] std::io::Error),
20    #[error("不支持网络路径")]
21    PathNotSupported,
22    #[error("文件大小不符合要求")]
23    InvalidFileSize,
24    #[error("{0}")]
25    HttpError(#[from] http::Error),
26    #[cfg(feature = "async")]
27    #[error("{0}")]
28    HyperError(#[from] hyper::Error),
29    #[cfg(feature = "async")]
30    #[error("{0}")]
31    HyperClientError(#[from] HyperClientError),
32    #[cfg(feature = "sync")]
33    #[error("{0}")]
34    RequestError(#[from] ureq::Error),
35    #[error("OSS返回了成功,但消息体结构解析失败,请尝试自行解析")]
36    OssInvalidResponse(Option<Bytes>),
37    #[error("{0} \n {1:#?}")]
38    OssError(StatusCode, OssError),
39    #[error("OSS返回了错误,HTTP状态码:{0},错误内容请自行解析")]
40    OssInvalidError(StatusCode, Bytes),
41    #[error("使用了不符合要求的字符")]
42    InvalidCharacter,
43    #[error("请求缺少必要的消息体,请检查调用参数")]
44    MissingRequestBody,
45}
46
47#[derive(Debug, Deserialize)]
48#[serde(rename = "Error")]
49pub struct OssError {
50    #[serde(rename = "Code")]
51    pub code: String,
52    #[serde(rename = "Message")]
53    pub message: String,
54    #[serde(rename = "RequestId")]
55    pub request_id: String,
56    #[serde(rename = "EC")]
57    pub ec: String,
58}
59
60#[cfg(feature = "async")]
61pub async fn normal_error(response: Response<Incoming>) -> Error {
62    let status_code = response.status();
63    let response_bytes = body_to_bytes(response.into_body()).await;
64    match response_bytes {
65        Err(e) => Error::HyperError(e),
66        Ok(response_bytes) => {
67            let oss_error = serde_xml_rs::from_reader(response_bytes.as_ref());
68            match oss_error {
69                Ok(oss_error) => Error::OssError(status_code, oss_error),
70                Err(_) => Error::OssInvalidError(status_code, response_bytes),
71            }
72        }
73    }
74}
75
76#[cfg(feature = "sync")]
77pub fn normal_error_sync(response: http::Response<Body>) -> Error {
78    let status_code = response.status();
79    let mut reader = response.into_body().into_reader();
80    let mut buf = Vec::new();
81    if let Err(e) = reader.read_to_end(&mut buf) {
82        return Error::IoError(e);
83    }
84    let bytes = Bytes::from(buf);
85    match serde_xml_rs::from_reader(bytes.as_ref()) {
86        Ok(oss_error) => Error::OssError(status_code, oss_error),
87        Err(_) => Error::OssInvalidError(status_code, bytes),
88    }
89}