use crate::fetch::webfinger::WebFingerError;
use http_signature_normalization_reqwest::SignError;
use rsa::{
errors::Error as RsaError,
pkcs8::{spki::Error as SpkiError, Error as Pkcs8Error},
};
use std::string::FromUtf8Error;
use tokio::task::JoinError;
use url::Url;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Object was not found in local database")]
NotFound,
#[error("Request limit was reached during fetch")]
RequestLimit,
#[error("Response body limit was reached during fetch")]
ResponseBodyLimit,
#[error("Fetched remote object {0} which was deleted")]
ObjectDeleted(Url),
#[error("URL failed verification: {0}")]
UrlVerificationError(&'static str),
#[error("Incoming activity has invalid digest for body")]
ActivityBodyDigestInvalid,
#[error("Incoming activity has invalid signature")]
ActivitySignatureInvalid,
#[error("Failed to resolve actor via webfinger")]
WebfingerResolveFailed(#[from] WebFingerError),
#[error("Failed to serialize outgoing activity {1}: {0}")]
SerializeOutgoingActivity(serde_json::Error, String),
#[error("Failed to parse object {1} with content {2}: {0}")]
ParseFetchedObject(serde_json::Error, Url, String),
#[error("Failed to parse incoming activity {}: {0}", match .1 {
Some(t) => format!("with id {t}"),
None => String::new(),
})]
ParseReceivedActivity(serde_json::Error, Option<Url>),
#[error(transparent)]
ReqwestMiddleware(#[from] reqwest_middleware::Error),
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
#[error(transparent)]
Utf8(#[from] FromUtf8Error),
#[error(transparent)]
UrlParse(#[from] url::ParseError),
#[error(transparent)]
SignError(#[from] SignError),
#[error("Failed to queue activity {0} for sending")]
ActivityQueueError(Url),
#[error(transparent)]
StopActivityQueue(#[from] JoinError),
#[error(
"Attempted to fetch object from {0} which doesn't have valid ActivityPub Content-Type"
)]
FetchInvalidContentType(Url),
#[error("Attempted to fetch object from {0} but the response's id field doesn't match")]
FetchWrongId(Url),
#[error(transparent)]
IoError(#[from] std::io::Error),
#[error("{0}")]
Other(String),
}
impl From<RsaError> for Error {
fn from(value: RsaError) -> Self {
Error::Other(value.to_string())
}
}
impl From<Pkcs8Error> for Error {
fn from(value: Pkcs8Error) -> Self {
Error::Other(value.to_string())
}
}
impl From<SpkiError> for Error {
fn from(value: SpkiError) -> Self {
Error::Other(value.to_string())
}
}
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
}