pub mod errno;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum NetDiskError {
#[error("HTTP request error: {status_code} - {url}")]
HttpError {
status_code: u16,
url: String,
source: Option<reqwest::Error>,
},
#[error("API error: {errno} - {errmsg}")]
ApiError { errno: i32, errmsg: String },
#[error("Authentication error: {description}")]
AuthError { description: String },
#[error("File already exists: {path}")]
FileExists { path: String },
#[error("File not found: {path}")]
FileNotFound { path: String },
#[error("Directory not found: {path}")]
DirectoryNotFound { path: String },
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("JSON parsing error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("URL encoding error: {0}")]
UrlEncodeError(String),
#[error("URL parsing error: {0}")]
UrlParseError(#[from] url::ParseError),
#[error("Request timed out")]
Timeout,
#[error("Request cancelled")]
Cancelled,
#[error("Invalid parameter: {message}")]
InvalidParameter { message: String },
#[error("Token expired")]
TokenExpired,
#[error("Synchronization primitive error: {0}")]
SyncError(String),
#[error("Invalid header value: {0}")]
InvalidHeaderValue(String),
#[error("HTTP client error: {0}")]
ReqwestError(#[from] reqwest::Error),
#[error("MPSC send error: {0}")]
MpscSendError(String),
#[error("Task join error: {0}")]
JoinError(#[from] tokio::task::JoinError),
#[error("Unknown error: {message}")]
Unknown { message: String },
}
impl NetDiskError {
pub fn http_error(status_code: u16, url: &str) -> Self {
NetDiskError::HttpError {
status_code,
url: url.to_string(),
source: None,
}
}
pub fn http_error_with_source(status_code: u16, url: &str, source: reqwest::Error) -> Self {
NetDiskError::HttpError {
status_code,
url: url.to_string(),
source: Some(source),
}
}
pub fn api_error(errno: i32, errmsg: &str) -> Self {
let description = errno::get_error_description(errno).unwrap_or(errmsg);
NetDiskError::ApiError {
errno,
errmsg: description.to_string(),
}
}
pub fn api_error_raw(errno: i32, errmsg: &str) -> Self {
NetDiskError::ApiError {
errno,
errmsg: errmsg.to_string(),
}
}
pub fn auth_error(description: &str) -> Self {
NetDiskError::AuthError {
description: description.to_string(),
}
}
pub fn invalid_parameter(message: &str) -> Self {
NetDiskError::InvalidParameter {
message: message.to_string(),
}
}
pub fn file_exists(path: &str) -> Self {
NetDiskError::FileExists {
path: path.to_string(),
}
}
pub fn file_not_found(path: &str) -> Self {
NetDiskError::FileNotFound {
path: path.to_string(),
}
}
pub fn directory_not_found(path: &str) -> Self {
NetDiskError::DirectoryNotFound {
path: path.to_string(),
}
}
pub fn is_auth_error(&self) -> bool {
match self {
NetDiskError::ApiError { errno, .. } => errno::is_auth_error(*errno),
NetDiskError::TokenExpired => true,
NetDiskError::AuthError { .. } => true,
_ => false,
}
}
pub fn is_not_found_error(&self) -> bool {
match self {
NetDiskError::ApiError { errno, .. } => errno::is_not_found_error(*errno),
NetDiskError::FileNotFound { .. } => true,
NetDiskError::DirectoryNotFound { .. } => true,
_ => false,
}
}
pub fn is_permission_error(&self) -> bool {
match self {
NetDiskError::ApiError { errno, .. } => errno::is_permission_error(*errno),
_ => false,
}
}
pub fn is_quota_error(&self) -> bool {
match self {
NetDiskError::ApiError { errno, .. } => errno::is_quota_error(*errno),
_ => false,
}
}
pub fn is_token_expired(&self) -> bool {
match self {
NetDiskError::ApiError { errno, .. } => errno::is_token_expired(*errno),
NetDiskError::TokenExpired => true,
_ => false,
}
}
}
pub type NetDiskResult<T> = Result<T, NetDiskError>;