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}