diff --git a/Cargo.lock b/Cargo.lock index d0c4507..a23e0aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1265,7 +1265,7 @@ dependencies = [ [[package]] name = "pict-rs-aggregator" -version = "0.1.10" +version = "0.1.11" dependencies = [ "actix-rt", "actix-web", diff --git a/Cargo.toml b/Cargo.toml index e0565d0..1b27691 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pict-rs-aggregator" description = "A simple image aggregation service for pict-rs" -version = "0.1.10" +version = "0.1.11" authors = ["asonix "] license = "AGPL-3.0" readme = "README.md" diff --git a/src/lib.rs b/src/lib.rs index da91cb6..0ec8410 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ use std::{ time::SystemTime, }; use structopt::StructOpt; +use tracing_error::SpanTrace; use url::Url; use uuid::Uuid; @@ -339,19 +340,50 @@ impl ResponseError for StateError { fn error_response(&self) -> HttpResponse { match rendered( - |cursor| self::templates::error(cursor, &self.error.to_string(), &self.state), + |cursor| self::templates::error(cursor, &self.error.kind.to_string(), &self.state), HttpResponse::build(self.status_code()), ) { Ok(res) => res, Err(_) => HttpResponse::build(self.status_code()) .content_type(mime::TEXT_PLAIN.essence_str()) - .body(self.error.to_string()), + .body(self.error.kind.to_string()), + } + } +} + +#[derive(Debug)] +struct Error { + context: SpanTrace, + kind: ErrorKind, +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}\n", self.kind)?; + std::fmt::Display::fmt(&self.context, f) + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.kind.source() + } +} + +impl From for Error +where + ErrorKind: From, +{ + fn from(error: T) -> Self { + Error { + context: SpanTrace::capture(), + kind: error.into(), } } } #[derive(Debug, thiserror::Error)] -enum Error { +enum ErrorKind { #[error("{0}")] Render(#[from] std::io::Error), @@ -455,13 +487,13 @@ async fn upload( let images = conn.upload(&req, pl).await.stateful(&state)?; if images.is_err() { - return Err(Error::UploadString(images.message().to_owned())).stateful(&state); + return Err(ErrorKind::UploadString(images.message().to_owned())).stateful(&state); } let image = images .files() .next() - .ok_or_else(|| Error::UploadString("Missing file".to_owned())) + .ok_or_else(|| ErrorKind::UploadString("Missing file".to_owned())) .stateful(&state)?; let entry = Entry { @@ -762,7 +794,7 @@ async fn delete_collection( for rx in future_vec { results.push( rx.await - .map_err(|_| Error::UploadString("Canceled".to_string())) + .map_err(|_| ErrorKind::UploadString("Canceled".to_string())) .stateful(&state)?, ); }