mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2026-01-30 19:15:17 +01:00
* feat: depot api downloads * feat: frontend fixes and experimental webview store * feat: sync downloader * feat: cleanup and fixes * feat: encrypted database and fixed resuming * feat: launch option selector * fix: autostart when no options * fix: clippy * fix: clippy x2 * feat: executor launch * feat: executor launch * feat: not installed error handling * feat: better offline handling * feat: dependency popup * fix: cancelation and resuming issues * feat: dedup by platform * feat: new ui for additional components and fix dl manager clog * feat: auto-queue dependencies * feat: depot scanning and ranking * feat: new library fetching stack * In-app store page (Windows + macOS) (#176) * feat: async store loading * feat: fix overscroll behaviour * fix: query params in server protocol * fix: clippy
161 lines
5.5 KiB
Rust
161 lines
5.5 KiB
Rust
use std::{
|
|
error::Error,
|
|
fmt::{Display, Formatter},
|
|
sync::Arc,
|
|
};
|
|
|
|
use http::{HeaderName, StatusCode, header::ToStrError};
|
|
use serde_with::SerializeDisplay;
|
|
use url::ParseError;
|
|
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Deserialize, Debug, Clone)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct DropServerError {
|
|
pub status_code: usize,
|
|
pub status_message: String,
|
|
pub message: String,
|
|
// pub url: String,
|
|
}
|
|
|
|
#[derive(Debug, SerializeDisplay)]
|
|
pub enum RemoteAccessError {
|
|
FetchErrorLegacy(Arc<reqwest::Error>),
|
|
FetchError(Arc<reqwest_middleware::Error>),
|
|
FetchErrorWS(Arc<reqwest_websocket::Error>),
|
|
ParsingError(ParseError),
|
|
InvalidEndpoint,
|
|
HandshakeFailed(String),
|
|
GameNotFound(String),
|
|
InvalidResponse(DropServerError),
|
|
UnparseableResponse(String),
|
|
ManifestDownloadFailed(StatusCode, String),
|
|
OutOfSync,
|
|
Cache(std::io::Error),
|
|
CorruptedState,
|
|
NoDepots,
|
|
}
|
|
|
|
impl Display for RemoteAccessError {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
RemoteAccessError::FetchError(error) => {
|
|
if error.is_connect() {
|
|
return write!(
|
|
f,
|
|
"Failed to connect to Drop server. Check if you access Drop through a browser, and then try again."
|
|
);
|
|
}
|
|
|
|
write!(
|
|
f,
|
|
"{}: {}",
|
|
error,
|
|
error
|
|
.source()
|
|
.map(std::string::ToString::to_string)
|
|
.unwrap_or("Unknown error".to_string())
|
|
)
|
|
}
|
|
RemoteAccessError::FetchErrorLegacy(error) => write!(
|
|
f,
|
|
"{}: {}",
|
|
error,
|
|
error
|
|
.source()
|
|
.map(|v| v.to_string())
|
|
.unwrap_or("Unknown error".to_string())
|
|
),
|
|
RemoteAccessError::FetchErrorWS(error) => write!(
|
|
f,
|
|
"{}: {}",
|
|
error,
|
|
error
|
|
.source()
|
|
.map(std::string::ToString::to_string)
|
|
.unwrap_or("Unknown error".to_string())
|
|
),
|
|
RemoteAccessError::ParsingError(parse_error) => {
|
|
write!(f, "{parse_error}")
|
|
}
|
|
RemoteAccessError::InvalidEndpoint => write!(f, "invalid drop endpoint"),
|
|
RemoteAccessError::HandshakeFailed(message) => {
|
|
write!(f, "failed to complete handshake: {message}")
|
|
}
|
|
RemoteAccessError::GameNotFound(id) => write!(f, "could not find game on server: {id}"),
|
|
RemoteAccessError::InvalidResponse(error) => write!(
|
|
f,
|
|
"server returned an invalid response: {}, {}",
|
|
error.status_code, error.message
|
|
),
|
|
RemoteAccessError::UnparseableResponse(error) => {
|
|
write!(f, "server returned an invalid response: {error}")
|
|
}
|
|
RemoteAccessError::ManifestDownloadFailed(status, response) => {
|
|
write!(f, "failed to download game manifest: {status} {response}")
|
|
}
|
|
RemoteAccessError::OutOfSync => write!(
|
|
f,
|
|
"server's and client's time are out of sync. Please ensure they are within at least 30 seconds of each other"
|
|
),
|
|
RemoteAccessError::Cache(error) => write!(f, "Cache Error: {error}"),
|
|
RemoteAccessError::CorruptedState => write!(
|
|
f,
|
|
"Drop encountered a corrupted internal state. Please report this to the developers, with details of reproduction."
|
|
),
|
|
RemoteAccessError::NoDepots => write!(f, "There are no download depots configured on the server. Contact your server admin."),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<reqwest::Error> for RemoteAccessError {
|
|
fn from(err: reqwest::Error) -> Self {
|
|
RemoteAccessError::FetchErrorLegacy(Arc::new(err))
|
|
}
|
|
}
|
|
impl From<reqwest_middleware::Error> for RemoteAccessError {
|
|
fn from(value: reqwest_middleware::Error) -> Self {
|
|
RemoteAccessError::FetchError(Arc::new(value))
|
|
}
|
|
}
|
|
impl From<reqwest_websocket::Error> for RemoteAccessError {
|
|
fn from(err: reqwest_websocket::Error) -> Self {
|
|
RemoteAccessError::FetchErrorWS(Arc::new(err))
|
|
}
|
|
}
|
|
impl From<ParseError> for RemoteAccessError {
|
|
fn from(err: ParseError) -> Self {
|
|
RemoteAccessError::ParsingError(err)
|
|
}
|
|
}
|
|
impl std::error::Error for RemoteAccessError {}
|
|
|
|
#[derive(Debug, SerializeDisplay)]
|
|
pub enum CacheError {
|
|
HeaderNotFound(HeaderName),
|
|
ParseError(ToStrError),
|
|
Remote(RemoteAccessError),
|
|
ConstructionError(http::Error),
|
|
}
|
|
|
|
impl Display for CacheError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let s = match self {
|
|
CacheError::HeaderNotFound(header_name) => {
|
|
format!("Could not find header {header_name} in cache")
|
|
}
|
|
CacheError::ParseError(to_str_error) => {
|
|
format!("Could not parse cache with error {to_str_error}")
|
|
}
|
|
CacheError::Remote(remote_access_error) => {
|
|
format!("Cache got remote access error: {remote_access_error}")
|
|
}
|
|
CacheError::ConstructionError(error) => {
|
|
format!("Could not construct cache body with error {error}")
|
|
}
|
|
};
|
|
write!(f, "{s}")
|
|
}
|
|
}
|