Update background-jobs, rework errors

This commit is contained in:
asonix 2024-02-05 00:24:49 -06:00
parent ed399f1531
commit b074759eb4
19 changed files with 189 additions and 140 deletions

69
Cargo.lock generated
View file

@ -389,12 +389,12 @@ dependencies = [
"actix-web",
"actix-webfinger",
"ammonia",
"anyhow",
"async-cpupool",
"background-jobs",
"base64",
"bcrypt",
"clap",
"color-eyre",
"config",
"console-subscriber",
"dashmap",
@ -564,9 +564,9 @@ dependencies = [
[[package]]
name = "background-jobs"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65f83277b60c9c889210ef54207cca1a8f7e6de916ad616ce4140d477c8a6094"
checksum = "50954581739942ccbf39f7723a250dd3044c32de2e2c7e5f8cf53cb35200136b"
dependencies = [
"background-jobs-core",
"background-jobs-metrics",
@ -575,11 +575,10 @@ dependencies = [
[[package]]
name = "background-jobs-core"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50ac54b76a9cb9bdf6bdb7a485181e9f9ab95e930aa34b6a74ebda76d04d6b11"
checksum = "dc0f2054eb1262a98306ef87d115c368aa1d38ecdf1cc5af08021e13eb0e55a8"
dependencies = [
"anyhow",
"async-trait",
"event-listener",
"metrics",
@ -593,9 +592,9 @@ dependencies = [
[[package]]
name = "background-jobs-metrics"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "119b921bdadd3bd666f8418054933e33b9d279203b8029c5881e3174c2821f79"
checksum = "617da80f3fe8fe9b042d07cab58cf92ba3098b2112c4c499a27f333ebab401d2"
dependencies = [
"async-trait",
"background-jobs-core",
@ -607,11 +606,10 @@ dependencies = [
[[package]]
name = "background-jobs-tokio"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d18cbc0bda6c07ffca4146ac88d93f93f93f374012a0c425c3a8b7fd34ccce4e"
checksum = "35759bf19b8b461e8d079f60565bf2ff8a76de36cdbe44d14de34cf4ae15c065"
dependencies = [
"anyhow",
"async-trait",
"background-jobs-core",
"metrics",
@ -864,6 +862,33 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]]
name = "color-eyre"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "colorchoice"
version = "1.0.0"
@ -1259,6 +1284,16 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "eyre"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "fastrand"
version = "2.0.1"
@ -1706,6 +1741,12 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d"
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "1.9.3"
@ -2357,6 +2398,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "parcel_selectors"
version = "0.26.4"

View file

@ -21,7 +21,6 @@ default = []
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"
actix-web = { version = "4.4.0", default-features = false, features = ["compress-brotli", "compress-gzip", "rustls-0_22"] }
actix-webfinger = { version = "0.5.0", default-features = false }
activitystreams = "0.7.0-alpha.25"
@ -31,6 +30,7 @@ async-cpupool = "0.2.0"
bcrypt = "0.15"
base64 = "0.21"
clap = { version = "4.0.0", features = ["derive"] }
color-eyre = "0.6.2"
config = { version = "0.14.0", default-features = false, features = ["toml", "json", "yaml"] }
console-subscriber = { version = "0.2", optional = true }
dashmap = "5.1.0"
@ -84,7 +84,7 @@ tokio = { version = "1", features = ["full", "tracing"] }
uuid = { version = "1", features = ["v4", "serde"] }
[dependencies.background-jobs]
version = "0.17.0"
version = "0.18.0"
default-features = false
features = ["error-logging", "metrics", "tokio"]
@ -102,7 +102,7 @@ features = ["middleware", "ring"]
version = "0.7.9"
[build-dependencies]
anyhow = "1.0"
color-eyre = "0.6.2"
dotenv = "0.15.0"
ructe = { version = "0.17.0", features = ["sass", "mime03"] }
toml = "0.8.0"

View file

@ -21,7 +21,7 @@ fn git_info() {
}
}
fn version_info() -> Result<(), anyhow::Error> {
fn version_info() -> color_eyre::Result<()> {
let cargo_toml = Path::new(&std::env::var("CARGO_MANIFEST_DIR")?).join("Cargo.toml");
let mut file = File::open(cargo_toml)?;
@ -42,7 +42,7 @@ fn version_info() -> Result<(), anyhow::Error> {
Ok(())
}
fn main() -> Result<(), anyhow::Error> {
fn main() -> color_eyre::Result<()> {
dotenv::dotenv().ok();
git_info();

View file

@ -4,54 +4,82 @@ use actix_web::{
http::StatusCode,
HttpResponse,
};
use background_jobs::BoxError;
use color_eyre::eyre::Error as Report;
use http_signature_normalization_reqwest::SignError;
use std::{convert::Infallible, fmt::Debug, io};
use std::{convert::Infallible, io, sync::Arc};
use tokio::task::JoinError;
use tracing_error::SpanTrace;
#[derive(Clone)]
struct ArcKind {
kind: Arc<ErrorKind>,
}
impl std::fmt::Debug for ArcKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.kind.fmt(f)
}
}
impl std::fmt::Display for ArcKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.kind.fmt(f)
}
}
impl std::error::Error for ArcKind {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.kind.source()
}
}
pub(crate) struct Error {
context: String,
kind: ErrorKind,
kind: ArcKind,
display: Box<str>,
debug: Box<str>,
}
impl Error {
fn kind(&self) -> &ErrorKind {
&self.kind.kind
}
pub(crate) fn is_breaker(&self) -> bool {
matches!(self.kind, ErrorKind::Breaker)
matches!(self.kind(), ErrorKind::Breaker)
}
pub(crate) fn is_not_found(&self) -> bool {
matches!(self.kind, ErrorKind::Status(_, StatusCode::NOT_FOUND))
matches!(self.kind(), ErrorKind::Status(_, StatusCode::NOT_FOUND))
}
pub(crate) fn is_bad_request(&self) -> bool {
matches!(self.kind, ErrorKind::Status(_, StatusCode::BAD_REQUEST))
matches!(self.kind(), ErrorKind::Status(_, StatusCode::BAD_REQUEST))
}
pub(crate) fn is_gone(&self) -> bool {
matches!(self.kind, ErrorKind::Status(_, StatusCode::GONE))
matches!(self.kind(), ErrorKind::Status(_, StatusCode::GONE))
}
pub(crate) fn is_malformed_json(&self) -> bool {
matches!(self.kind, ErrorKind::Json(_))
matches!(self.kind(), ErrorKind::Json(_))
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{:?}", self.kind)
f.write_str(&self.debug)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}", self.kind)?;
std::fmt::Display::fmt(&self.context, f)
f.write_str(&self.display)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.kind.source()
self.kind().source()
}
}
@ -60,25 +88,36 @@ where
ErrorKind: From<T>,
{
fn from(error: T) -> Self {
let kind = ArcKind {
kind: Arc::new(ErrorKind::from(error)),
};
let report = Report::new(kind.clone());
let display = format!("{report}");
let debug = format!("{report:?}");
Error {
context: SpanTrace::capture().to_string(),
kind: error.into(),
kind,
display: Box::from(display),
debug: Box::from(debug),
}
}
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum ErrorKind {
#[error("Error queueing job, {0}")]
Queue(anyhow::Error),
#[error("Error in extractor")]
Extractor(#[from] crate::extractors::ErrorKind),
#[error("Error in configuration, {0}")]
#[error("Error queueing job")]
Queue(#[from] BoxError),
#[error("Error in configuration")]
Config(#[from] config::ConfigError),
#[error("Couldn't parse key, {0}")]
#[error("Couldn't parse key")]
Pkcs8(#[from] rsa::pkcs8::Error),
#[error("Couldn't encode public key, {0}")]
#[error("Couldn't encode public key")]
Spki(#[from] rsa::pkcs8::spki::Error),
#[error("Couldn't sign request")]
@ -90,25 +129,25 @@ pub(crate) enum ErrorKind {
#[error("Couldn't make request")]
ReqwestMiddleware(#[from] reqwest_middleware::Error),
#[error("Couldn't parse IRI, {0}")]
#[error("Couldn't parse IRI")]
ParseIri(#[from] activitystreams::iri_string::validate::Error),
#[error("Couldn't normalize IRI, {0}")]
#[error("Couldn't normalize IRI")]
NormalizeIri(#[from] std::collections::TryReserveError),
#[error("Couldn't perform IO, {0}")]
#[error("Couldn't perform IO")]
Io(#[from] io::Error),
#[error("Couldn't sign string, {0}")]
Rsa(rsa::errors::Error),
#[error("Couldn't use db, {0}")]
#[error("Couldn't use db")]
Sled(#[from] sled::Error),
#[error("Couldn't do the json thing, {0}")]
#[error("Couldn't do the json thing")]
Json(#[from] serde_json::Error),
#[error("Couldn't sign request, {0}")]
#[error("Couldn't sign request")]
Sign(#[from] SignError),
#[error("Couldn't sign digest")]
@ -147,10 +186,10 @@ pub(crate) enum ErrorKind {
#[error("Wrong ActivityPub kind, {0}")]
Kind(String),
#[error("Too many CPUs, {0}")]
#[error("Too many CPUs")]
CpuCount(#[from] std::num::TryFromIntError),
#[error("{0}")]
#[error("Host mismatch")]
HostMismatch(#[from] CheckError),
#[error("Couldn't flush buffer")]
@ -204,7 +243,7 @@ pub(crate) enum ErrorKind {
impl ResponseError for Error {
fn status_code(&self) -> StatusCode {
match self.kind {
match self.kind() {
ErrorKind::NotAllowed(_) | ErrorKind::WrongActor(_) | ErrorKind::BadActor(_, _) => {
StatusCode::FORBIDDEN
}
@ -224,7 +263,7 @@ impl ResponseError for Error {
.insert_header(("Content-Type", "application/activity+json"))
.body(
serde_json::to_string(&serde_json::json!({
"error": self.kind.to_string(),
"error": self.kind().to_string(),
}))
.unwrap_or_else(|_| "{}".to_string()),
)

View file

@ -1,19 +1,15 @@
use actix_web::{
dev::Payload,
error::ParseError,
http::{
header::{from_one_raw_str, Header, HeaderName, HeaderValue, TryIntoHeaderValue},
StatusCode,
},
http::header::{from_one_raw_str, Header, HeaderName, HeaderValue, TryIntoHeaderValue},
web::Data,
FromRequest, HttpMessage, HttpRequest, HttpResponse, ResponseError,
FromRequest, HttpMessage, HttpRequest,
};
use bcrypt::{BcryptError, DEFAULT_COST};
use http_signature_normalization_actix::{prelude::InvalidHeaderValue, Canceled, Spawn};
use std::{convert::Infallible, str::FromStr, time::Instant};
use tracing_error::SpanTrace;
use crate::{db::Db, future::LocalBoxFuture, spawner::Spawner};
use crate::{db::Db, error::Error, future::LocalBoxFuture, spawner::Spawner};
#[derive(Clone)]
pub(crate) struct AdminConfig {
@ -83,74 +79,42 @@ impl Admin {
}
}
#[derive(Debug, thiserror::Error)]
#[error("Failed authentication")]
pub(crate) struct Error {
context: String,
#[source]
kind: ErrorKind,
}
impl Error {
fn invalid() -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::Invalid,
}
Error::from(ErrorKind::Invalid)
}
fn missing_config() -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::MissingConfig,
}
Error::from(ErrorKind::MissingConfig)
}
fn missing_db() -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::MissingDb,
}
Error::from(ErrorKind::MissingDb)
}
fn missing_spawner() -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::MissingSpawner,
}
Error::from(ErrorKind::MissingSpawner)
}
fn bcrypt_verify(e: BcryptError) -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::BCryptVerify(e),
}
Error::from(ErrorKind::BCryptVerify(e))
}
fn bcrypt_hash(e: BcryptError) -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::BCryptHash(e),
}
Error::from(ErrorKind::BCryptHash(e))
}
fn parse_header(e: ParseError) -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::ParseHeader(e),
}
Error::from(ErrorKind::ParseHeader(e))
}
fn canceled(_: Canceled) -> Self {
Error {
context: SpanTrace::capture().to_string(),
kind: ErrorKind::Canceled,
}
Error::from(ErrorKind::Canceled)
}
}
#[derive(Debug, thiserror::Error)]
enum ErrorKind {
pub(crate) enum ErrorKind {
#[error("Invalid API Token")]
Invalid,
@ -176,20 +140,6 @@ enum ErrorKind {
ParseHeader(#[source] ParseError),
}
impl ResponseError for Error {
fn status_code(&self) -> StatusCode {
match self.kind {
ErrorKind::Invalid | ErrorKind::ParseHeader(_) => StatusCode::BAD_REQUEST,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code())
.json(serde_json::json!({ "msg": self.kind.to_string() }))
}
}
impl FromRequest for Admin {
type Error = Error;
type Future = LocalBoxFuture<'static, Result<Self, Self::Error>>;

View file

@ -64,12 +64,13 @@ fn generate_announce(
impl Job for Announce {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::apub::Announce";
const QUEUE: &'static str = "apub";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -113,12 +113,13 @@ fn generate_accept_follow(
impl Job for Follow {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::apub::Follow";
const QUEUE: &'static str = "apub";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -49,12 +49,13 @@ impl Forward {
impl Job for Forward {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::apub::Forward";
const QUEUE: &'static str = "apub";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -35,12 +35,13 @@ impl Reject {
impl Job for Reject {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::apub::Reject";
const QUEUE: &'static str = "apub";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -50,12 +50,13 @@ impl Undo {
impl Job for Undo {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::apub::Undo";
const QUEUE: &'static str = "apub";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -87,13 +87,14 @@ fn to_contact(contact: AcceptedActors) -> Option<(String, String, IriString, Iri
impl Job for QueryContact {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::QueryContact";
const QUEUE: &'static str = "maintenance";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -35,7 +35,7 @@ impl Deliver {
}
#[tracing::instrument(name = "Deliver", skip(state))]
async fn permform(self, state: JobState) -> Result<(), Error> {
async fn perform(self, state: JobState) -> Result<(), Error> {
if let Err(e) = state
.state
.requests
@ -58,13 +58,14 @@ impl Deliver {
impl Job for Deliver {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::Deliver";
const QUEUE: &'static str = "deliver";
const BACKOFF: Backoff = Backoff::Exponential(8);
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.permform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -47,12 +47,13 @@ impl DeliverMany {
impl Job for DeliverMany {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::DeliverMany";
const QUEUE: &'static str = "deliver";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -167,13 +167,14 @@ impl QueryInstance {
impl Job for QueryInstance {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::QueryInstance";
const QUEUE: &'static str = "maintenance";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -106,13 +106,14 @@ impl QueryNodeinfo {
impl Job for QueryNodeinfo {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::QueryNodeinfo";
const QUEUE: &'static str = "maintenance";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -25,12 +25,13 @@ impl Listeners {
impl Job for Listeners {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::Listeners";
const QUEUE: &'static str = "maintenance";
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -15,13 +15,14 @@ impl RecordLastOnline {
impl Job for RecordLastOnline {
type State = JobState;
type Future = BoxFuture<'static, anyhow::Result<()>>;
type Error = Error;
type Future = BoxFuture<'static, Result<(), Self::Error>>;
const NAME: &'static str = "relay::jobs::RecordLastOnline";
const QUEUE: &'static str = "maintenance";
const BACKOFF: Backoff = Backoff::Linear(1);
fn run(self, state: Self::State) -> Self::Future {
Box::pin(async move { self.perform(state).await.map_err(Into::into) })
Box::pin(self.perform(state))
}
}

View file

@ -56,8 +56,9 @@ use self::{
fn init_subscriber(
software_name: &'static str,
opentelemetry_url: Option<&IriString>,
) -> Result<(), anyhow::Error> {
) -> color_eyre::Result<()> {
LogTracer::init()?;
color_eyre::install()?;
let targets: Targets = std::env::var("RUST_LOG")
.unwrap_or_else(|_| "info".into())
@ -140,7 +141,7 @@ fn build_client(
}
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
async fn main() -> color_eyre::Result<()> {
dotenv::dotenv().ok();
let config = Config::build()?;
@ -166,7 +167,7 @@ async fn main() -> Result<(), anyhow::Error> {
.add_recorder(recorder)
.add_recorder(collector.clone())
.build();
metrics::set_global_recorder(recorder).map_err(|e| anyhow::anyhow!("{e}"))?;
metrics::set_global_recorder(recorder).map_err(|e| color_eyre::eyre::eyre!("{e}"))?;
} else {
collector.install()?;
}
@ -185,11 +186,11 @@ async fn main() -> Result<(), anyhow::Error> {
Ok(())
}
fn client_main(config: Config, args: Args) -> JoinHandle<Result<(), anyhow::Error>> {
fn client_main(config: Config, args: Args) -> JoinHandle<color_eyre::Result<()>> {
tokio::spawn(do_client_main(config, args))
}
async fn do_client_main(config: Config, args: Args) -> Result<(), anyhow::Error> {
async fn do_client_main(config: Config, args: Args) -> color_eyre::Result<()> {
let client = build_client(
&config.user_agent(),
config.client_timeout(),
@ -280,7 +281,7 @@ async fn server_main(
media: MediaCache,
collector: MemoryCollector,
config: Config,
) -> Result<(), anyhow::Error> {
) -> color_eyre::Result<()> {
let client = build_client(
&config.user_agent(),
config.client_timeout(),

View file

@ -8,7 +8,7 @@ pub(crate) struct Spawner {
}
impl Spawner {
pub(crate) fn build(name: &'static str, threads: u16) -> anyhow::Result<Self> {
pub(crate) fn build(name: &'static str, threads: u16) -> color_eyre::Result<Self> {
let pool = CpuPool::configure()
.name(name)
.max_threads(threads)