Use color-eyre

This commit is contained in:
Aode (Lion) 2022-03-28 20:47:46 -05:00
parent 1291bf8beb
commit eb5e39c634
13 changed files with 211 additions and 102 deletions

95
Cargo.lock generated
View file

@ -219,6 +219,15 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "addr2line"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
]
[[package]] [[package]]
name = "adler" name = "adler"
version = "1.0.2" version = "1.0.2"
@ -372,6 +381,21 @@ dependencies = [
"anyhow", "anyhow",
] ]
[[package]]
name = "backtrace"
version = "0.3.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.13.0" version = "0.13.0"
@ -498,6 +522,33 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "color-eyre"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ebf286c900a6d5867aeff75cfee3192857bb7f24b547d4f0df2ed6baa812c90"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]] [[package]]
name = "config" name = "config"
version = "0.12.0" version = "0.12.0"
@ -734,6 +785,16 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "eyre"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9289ed2c0440a6536e65119725cf91fc2c6b5e513bfd2e36e1134d7cca6ca12f"
dependencies = [
"indenter",
"once_cell",
]
[[package]] [[package]]
name = "fake-simd" name = "fake-simd"
version = "0.1.2" version = "0.1.2"
@ -926,6 +987,12 @@ dependencies = [
"wasi 0.10.2+wasi-snapshot-preview1", "wasi 0.10.2+wasi-snapshot-preview1",
] ]
[[package]]
name = "gimli"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.12" version = "0.3.12"
@ -1122,6 +1189,12 @@ dependencies = [
"unicode-normalization", "unicode-normalization",
] ]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.8.0" version = "1.8.0"
@ -1403,6 +1476,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "object"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.10.0" version = "1.10.0"
@ -1489,6 +1571,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "owo-colors"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e72e30578e0d0993c8ae20823dd9cff2bc5517d2f586a8aef462a581e8a03eb"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.2" version = "0.11.2"
@ -1621,6 +1709,7 @@ dependencies = [
"awc", "awc",
"base64", "base64",
"clap", "clap",
"color-eyre",
"config", "config",
"console-subscriber", "console-subscriber",
"dashmap", "dashmap",
@ -1997,6 +2086,12 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.0" version = "0.4.0"

View file

@ -28,6 +28,7 @@ async-trait = "0.1.51"
awc = { version = "3.0.0", default-features = false, features = ["rustls"] } awc = { version = "3.0.0", default-features = false, features = ["rustls"] }
base64 = "0.13.0" base64 = "0.13.0"
clap = { version = "3.1.6", features = ["derive"] } clap = { version = "3.1.6", features = ["derive"] }
color-eyre = "0.6"
config = "0.12.0" config = "0.12.0"
console-subscriber = "0.1" console-subscriber = "0.1"
dashmap = "5.1.0" dashmap = "5.1.0"
@ -76,9 +77,9 @@ uuid = { version = "0.8.2", features = ["v4", "serde"] }
[dependencies.tracing-actix-web] [dependencies.tracing-actix-web]
version = "0.5.0" version = "0.5.0"
default-features = false default-features = false
features = ["emit_event_on_error", "opentelemetry_0_17"] features = ["opentelemetry_0_17"]
[dependencies.tracing-awc] [dependencies.tracing-awc]
version = "0.1.0" version = "0.1.0"
default-features = false default-features = false
features = ["emit_event_on_error", "opentelemetry_0_17"] features = ["opentelemetry_0_17"]

View file

@ -13,7 +13,7 @@ pub(crate) use commandline::Operation;
pub(crate) use file::{ConfigFile as Configuration, OpenTelemetry, Repo, Sled, Tracing}; pub(crate) use file::{ConfigFile as Configuration, OpenTelemetry, Repo, Sled, Tracing};
pub(crate) use primitives::{Filesystem, ImageFormat, LogFormat, ObjectStorage, Store}; pub(crate) use primitives::{Filesystem, ImageFormat, LogFormat, ObjectStorage, Store};
pub(crate) fn configure() -> anyhow::Result<(Configuration, Operation)> { pub(crate) fn configure() -> color_eyre::Result<(Configuration, Operation)> {
let Output { let Output {
config_format, config_format,
operation, operation,

View file

@ -2,7 +2,7 @@ use crate::{
config::primitives::{ImageFormat, LogFormat, Store, Targets}, config::primitives::{ImageFormat, LogFormat, Store, Targets},
serde_str::Serde, serde_str::Serde,
}; };
use std::{collections::HashSet, net::SocketAddr, path::PathBuf}; use std::{collections::BTreeSet, net::SocketAddr, path::PathBuf};
use url::Url; use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
@ -94,7 +94,7 @@ pub(crate) struct Media {
pub(crate) enable_silent_video: bool, pub(crate) enable_silent_video: bool,
pub(crate) filters: HashSet<String>, pub(crate) filters: BTreeSet<String>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub(crate) format: Option<ImageFormat>, pub(crate) format: Option<ImageFormat>,

View file

@ -1,50 +1,31 @@
use actix_web::{http::StatusCode, HttpResponse, ResponseError}; use actix_web::{http::StatusCode, HttpResponse, ResponseError};
use tracing_error::SpanTrace; use color_eyre::Report;
pub(crate) struct Error { pub(crate) struct Error {
context: SpanTrace, inner: color_eyre::Report,
kind: UploadError, }
impl Error {
fn kind(&self) -> Option<&UploadError> {
self.inner.downcast_ref()
}
} }
impl std::fmt::Debug for Error { impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}", self.kind) std::fmt::Debug::fmt(&self.inner, f)
} }
} }
impl std::fmt::Display for Error { impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}", self.kind)?; std::fmt::Display::fmt(&self.inner, f)
writeln!(f)?;
writeln!(f, "Chain:")?;
fmt_chain(f, &self.kind)?;
writeln!(f)?;
writeln!(f, "Spantrace:")?;
std::fmt::Display::fmt(&self.context, f)
} }
} }
fn fmt_chain(
f: &mut std::fmt::Formatter<'_>,
err: &dyn std::error::Error,
) -> Result<usize, std::fmt::Error> {
let count = if let Some(source) = std::error::Error::source(err) {
fmt_chain(f, source)?
} else {
0
};
write!(f, "\t{}. ", count)?;
writeln!(f, "{}", err)?;
Ok(count + 1)
}
impl std::error::Error for Error { impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.kind.source() self.inner.source()
} }
} }
@ -54,8 +35,7 @@ where
{ {
fn from(error: T) -> Self { fn from(error: T) -> Self {
Error { Error {
kind: UploadError::from(error), inner: Report::from(UploadError::from(error)),
context: SpanTrace::capture(),
} }
} }
} }
@ -158,25 +138,38 @@ impl From<tokio::sync::AcquireError> for UploadError {
impl ResponseError for Error { impl ResponseError for Error {
fn status_code(&self) -> StatusCode { fn status_code(&self) -> StatusCode {
match self.kind { match self.kind() {
UploadError::DuplicateAlias Some(
| UploadError::Limit(_) UploadError::DuplicateAlias
| UploadError::NoFiles | UploadError::Limit(_)
| UploadError::Upload(_) => StatusCode::BAD_REQUEST, | UploadError::NoFiles
UploadError::Sled(crate::repo::sled::SledError::Missing) | UploadError::Upload(_),
| UploadError::MissingAlias => StatusCode::NOT_FOUND, ) => StatusCode::BAD_REQUEST,
UploadError::InvalidToken => StatusCode::FORBIDDEN, Some(
UploadError::Range => StatusCode::RANGE_NOT_SATISFIABLE, UploadError::Sled(crate::repo::sled::SledError::Missing)
| UploadError::MissingAlias,
) => StatusCode::NOT_FOUND,
Some(UploadError::InvalidToken) => StatusCode::FORBIDDEN,
Some(UploadError::Range) => StatusCode::RANGE_NOT_SATISFIABLE,
_ => StatusCode::INTERNAL_SERVER_ERROR, _ => StatusCode::INTERNAL_SERVER_ERROR,
} }
} }
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code()) if let Some(kind) = self.kind() {
.content_type("application/json") HttpResponse::build(self.status_code())
.body( .content_type("application/json")
serde_json::to_string(&serde_json::json!({ "msg": self.kind.to_string() })) .body(
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()), serde_json::to_string(&serde_json::json!({ "msg": kind.to_string() }))
) .unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
)
} else {
HttpResponse::build(self.status_code())
.content_type("application/json")
.body(
serde_json::to_string(&serde_json::json!({ "msg": "Unknown error" }))
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
)
}
} }
} }

View file

@ -12,7 +12,9 @@ use tracing_subscriber::{
fmt::format::FmtSpan, layer::SubscriberExt, registry::LookupSpan, Layer, Registry, fmt::format::FmtSpan, layer::SubscriberExt, registry::LookupSpan, Layer, Registry,
}; };
pub(super) fn init_tracing(tracing: &Tracing) -> anyhow::Result<()> { pub(super) fn init_tracing(tracing: &Tracing) -> color_eyre::Result<()> {
color_eyre::install()?;
LogTracer::init()?; LogTracer::init()?;
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new()); opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
@ -28,7 +30,7 @@ pub(super) fn init_tracing(tracing: &Tracing) -> anyhow::Result<()> {
} }
} }
fn with_format<F>(format_layer: F, tracing: &Tracing) -> anyhow::Result<()> fn with_format<F>(format_layer: F, tracing: &Tracing) -> color_eyre::Result<()>
where where
F: Layer<Registry> + Send + Sync, F: Layer<Registry> + Send + Sync,
{ {
@ -53,7 +55,7 @@ where
} }
} }
fn with_subscriber<S>(subscriber: S, otel: &OpenTelemetry) -> anyhow::Result<()> fn with_subscriber<S>(subscriber: S, otel: &OpenTelemetry) -> color_eyre::Result<()>
where where
S: SubscriberExt + Send + Sync, S: SubscriberExt + Send + Sync,
for<'a> S: LookupSpan<'a>, for<'a> S: LookupSpan<'a>,

View file

@ -11,7 +11,7 @@ use futures_util::{
}; };
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{ use std::{
collections::HashSet, collections::BTreeSet,
future::ready, future::ready,
path::PathBuf, path::PathBuf,
pin::Pin, pin::Pin,
@ -263,7 +263,7 @@ type ProcessQuery = Vec<(String, String)>;
fn prepare_process( fn prepare_process(
query: web::Query<ProcessQuery>, query: web::Query<ProcessQuery>,
ext: &str, ext: &str,
filters: &HashSet<String>, filters: &BTreeSet<String>,
) -> Result<(ImageFormat, Alias, PathBuf, Vec<String>), Error> { ) -> Result<(ImageFormat, Alias, PathBuf, Vec<String>), Error> {
let (alias, operations) = let (alias, operations) =
query query
@ -306,7 +306,7 @@ async fn process_details<S: Store>(
ext: web::Path<String>, ext: web::Path<String>,
manager: web::Data<UploadManager>, manager: web::Data<UploadManager>,
store: web::Data<S>, store: web::Data<S>,
filters: web::Data<HashSet<String>>, filters: web::Data<BTreeSet<String>>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let (_, alias, thumbnail_path, _) = prepare_process(query, ext.as_str(), &filters)?; let (_, alias, thumbnail_path, _) = prepare_process(query, ext.as_str(), &filters)?;
@ -330,7 +330,7 @@ async fn process<S: Store + 'static>(
ext: web::Path<String>, ext: web::Path<String>,
manager: web::Data<UploadManager>, manager: web::Data<UploadManager>,
store: web::Data<S>, store: web::Data<S>,
filters: web::Data<HashSet<String>>, filters: web::Data<BTreeSet<String>>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let (format, alias, thumbnail_path, thumbnail_args) = let (format, alias, thumbnail_path, thumbnail_args) =
prepare_process(query, ext.as_str(), &filters)?; prepare_process(query, ext.as_str(), &filters)?;
@ -635,7 +635,7 @@ fn build_reqwest_client() -> reqwest::Result<reqwest::Client> {
async fn launch<S: Store + Clone + 'static>( async fn launch<S: Store + Clone + 'static>(
manager: UploadManager, manager: UploadManager,
store: S, store: S,
) -> anyhow::Result<()> { ) -> color_eyre::Result<()> {
// Create a new Multipart Form validator // Create a new Multipart Form validator
// //
// This form is expecting a single array field, 'images' with at most 10 files in it // This form is expecting a single array field, 'images' with at most 10 files in it
@ -769,7 +769,7 @@ async fn migrate_inner<S1>(
repo: &Repo, repo: &Repo,
from: S1, from: S1,
to: &config::Store, to: &config::Store,
) -> anyhow::Result<()> ) -> color_eyre::Result<()>
where where
S1: Store, S1: Store,
{ {
@ -806,7 +806,7 @@ where
} }
#[actix_rt::main] #[actix_rt::main]
async fn main() -> anyhow::Result<()> { async fn main() -> color_eyre::Result<()> {
init_tracing(&CONFIG.tracing)?; init_tracing(&CONFIG.tracing)?;
let repo = Repo::open(CONFIG.repo.clone())?; let repo = Repo::open(CONFIG.repo.clone())?;

View file

@ -1,14 +1,14 @@
use crate::UploadError; use crate::Error;
use std::path::PathBuf; use std::path::PathBuf;
mod s034; mod s034;
type SledIter = Box<dyn Iterator<Item = Result<(Vec<u8>, Vec<u8>), UploadError>>>; type SledIter = Box<dyn Iterator<Item = Result<(Vec<u8>, Vec<u8>), Error>>>;
trait SledDb { trait SledDb {
type SledTree: SledTree; type SledTree: SledTree;
fn open_tree(&self, name: &str) -> Result<Self::SledTree, UploadError>; fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error>;
fn self_tree(&self) -> &Self::SledTree; fn self_tree(&self) -> &Self::SledTree;
} }
@ -19,7 +19,7 @@ where
{ {
type SledTree = T::SledTree; type SledTree = T::SledTree;
fn open_tree(&self, name: &str) -> Result<Self::SledTree, UploadError> { fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error> {
(*self).open_tree(name) (*self).open_tree(name)
} }
@ -29,11 +29,11 @@ where
} }
trait SledTree { trait SledTree {
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, UploadError> fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, Error>
where where
K: AsRef<[u8]>; K: AsRef<[u8]>;
fn insert<K, V>(&self, key: K, value: V) -> Result<(), UploadError> fn insert<K, V>(&self, key: K, value: V) -> Result<(), Error>
where where
K: AsRef<[u8]>, K: AsRef<[u8]>,
V: AsRef<[u8]>; V: AsRef<[u8]>;
@ -45,7 +45,7 @@ trait SledTree {
K: AsRef<[u8]>, K: AsRef<[u8]>,
R: std::ops::RangeBounds<K>; R: std::ops::RangeBounds<K>;
fn flush(&self) -> Result<(), UploadError>; fn flush(&self) -> Result<(), Error>;
} }
pub(crate) struct LatestDb { pub(crate) struct LatestDb {
@ -60,7 +60,7 @@ impl LatestDb {
LatestDb { root_dir, version } LatestDb { root_dir, version }
} }
pub(crate) fn migrate(self) -> Result<sled::Db, UploadError> { pub(crate) fn migrate(self) -> Result<sled::Db, Error> {
let LatestDb { root_dir, version } = self; let LatestDb { root_dir, version } = self;
loop { loop {
@ -89,7 +89,7 @@ impl DbVersion {
DbVersion::Fresh DbVersion::Fresh
} }
fn migrate(self, root: PathBuf) -> Result<sled::Db, UploadError> { fn migrate(self, root: PathBuf) -> Result<sled::Db, Error> {
match self { match self {
DbVersion::Sled034 | DbVersion::Fresh => s034::open(root), DbVersion::Sled034 | DbVersion::Fresh => s034::open(root),
} }

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
error::Error,
migrate::{SledDb, SledIter, SledTree}, migrate::{SledDb, SledIter, SledTree},
UploadError,
}; };
use sled as sled034; use sled as sled034;
use std::path::PathBuf; use std::path::PathBuf;
@ -26,7 +26,7 @@ pub(crate) fn migrating(base: PathBuf) -> bool {
true true
} }
pub(crate) fn open(mut base: PathBuf) -> Result<sled034::Db, UploadError> { pub(crate) fn open(mut base: PathBuf) -> Result<sled034::Db, Error> {
base.push("sled"); base.push("sled");
base.push(SLED_034); base.push(SLED_034);
@ -41,7 +41,7 @@ pub(crate) fn open(mut base: PathBuf) -> Result<sled034::Db, UploadError> {
impl SledDb for sled034::Db { impl SledDb for sled034::Db {
type SledTree = sled034::Tree; type SledTree = sled034::Tree;
fn open_tree(&self, name: &str) -> Result<Self::SledTree, UploadError> { fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error> {
Ok(sled034::Db::open_tree(self, name)?) Ok(sled034::Db::open_tree(self, name)?)
} }
@ -51,14 +51,14 @@ impl SledDb for sled034::Db {
} }
impl SledTree for sled034::Tree { impl SledTree for sled034::Tree {
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, UploadError> fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, Error>
where where
K: AsRef<[u8]>, K: AsRef<[u8]>,
{ {
Ok(sled034::Tree::get(self, key)?.map(|v| Vec::from(v.as_ref()))) Ok(sled034::Tree::get(self, key)?.map(|v| Vec::from(v.as_ref())))
} }
fn insert<K, V>(&self, key: K, value: V) -> Result<(), UploadError> fn insert<K, V>(&self, key: K, value: V) -> Result<(), Error>
where where
K: AsRef<[u8]>, K: AsRef<[u8]>,
V: AsRef<[u8]>, V: AsRef<[u8]>,
@ -69,7 +69,7 @@ impl SledTree for sled034::Tree {
fn iter(&self) -> SledIter { fn iter(&self) -> SledIter {
Box::new(sled034::Tree::iter(self).map(|res| { Box::new(sled034::Tree::iter(self).map(|res| {
res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec())) res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec()))
.map_err(UploadError::from) .map_err(Error::from)
})) }))
} }
@ -80,13 +80,11 @@ impl SledTree for sled034::Tree {
{ {
Box::new(sled034::Tree::range(self, range).map(|res| { Box::new(sled034::Tree::range(self, range).map(|res| {
res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec())) res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec()))
.map_err(UploadError::from) .map_err(Error::from)
})) }))
} }
fn flush(&self) -> Result<(), UploadError> { fn flush(&self) -> Result<(), Error> {
sled034::Tree::flush(self) sled034::Tree::flush(self).map(|_| ()).map_err(Error::from)
.map(|_| ())
.map_err(UploadError::from)
} }
} }

View file

@ -24,7 +24,7 @@ pub(crate) fn build_chain(
args: &[(String, String)], args: &[(String, String)],
ext: &str, ext: &str,
) -> Result<(PathBuf, Vec<String>), Error> { ) -> Result<(PathBuf, Vec<String>), Error> {
fn parse<P: Processor>(key: &str, value: &str) -> Result<Option<P>, UploadError> { fn parse<P: Processor>(key: &str, value: &str) -> Result<Option<P>, Error> {
if key == P::NAME { if key == P::NAME {
return Ok(Some(P::parse(key, value).ok_or(UploadError::ParsePath)?)); return Ok(Some(P::parse(key, value).ok_or(UploadError::ParsePath)?));
} }

View file

@ -120,7 +120,7 @@ pub(crate) trait AliasRepo {
} }
impl Repo { impl Repo {
pub(crate) fn open(config: config::Repo) -> anyhow::Result<Self> { pub(crate) fn open(config: config::Repo) -> color_eyre::Result<Self> {
match config { match config {
config::Repo::Sled(config::Sled { config::Repo::Sled(config::Sled {
mut path, mut path,
@ -139,7 +139,7 @@ impl Repo {
} }
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub(crate) async fn from_db(&self, db: ::sled::Db) -> anyhow::Result<()> { pub(crate) async fn from_db(&self, db: ::sled::Db) -> color_eyre::Result<()> {
if self.has_migrated().await? { if self.has_migrated().await? {
return Ok(()); return Ok(());
} }
@ -161,13 +161,13 @@ impl Repo {
Ok(()) Ok(())
} }
async fn has_migrated(&self) -> anyhow::Result<bool> { async fn has_migrated(&self) -> color_eyre::Result<bool> {
match self { match self {
Self::Sled(repo) => Ok(repo.get(REPO_MIGRATION_O1).await?.is_some()), Self::Sled(repo) => Ok(repo.get(REPO_MIGRATION_O1).await?.is_some()),
} }
} }
async fn mark_migrated(&self) -> anyhow::Result<()> { async fn mark_migrated(&self) -> color_eyre::Result<()> {
match self { match self {
Self::Sled(repo) => { Self::Sled(repo) => {
repo.set(REPO_MIGRATION_O1, b"1".to_vec().into()).await?; repo.set(REPO_MIGRATION_O1, b"1".to_vec().into()).await?;
@ -182,7 +182,7 @@ const REPO_MIGRATION_O1: &[u8] = b"repo-migration-01";
const STORE_MIGRATION_PROGRESS: &[u8] = b"store-migration-progress"; const STORE_MIGRATION_PROGRESS: &[u8] = b"store-migration-progress";
const GENERATOR_KEY: &[u8] = b"last-path"; const GENERATOR_KEY: &[u8] = b"last-path";
async fn migrate_hash<T>(repo: &T, old: &old::Old, hash: ::sled::IVec) -> anyhow::Result<()> async fn migrate_hash<T>(repo: &T, old: &old::Old, hash: ::sled::IVec) -> color_eyre::Result<()>
where where
T: IdentifierRepo + HashRepo + AliasRepo + SettingsRepo, T: IdentifierRepo + HashRepo + AliasRepo + SettingsRepo,
{ {

View file

@ -17,9 +17,19 @@
// - Settings Tree // - Settings Tree
// - store-migration-progress -> Path Tree Key // - store-migration-progress -> Path Tree Key
use super::{Alias, DeleteToken, Details};
use std::path::PathBuf; use std::path::PathBuf;
use super::{Alias, DeleteToken, Details}; #[derive(Debug)]
struct OldDbError(&'static str);
impl std::fmt::Display for OldDbError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::error::Error for OldDbError {}
pub(super) struct Old { pub(super) struct Old {
alias_tree: ::sled::Tree, alias_tree: ::sled::Tree,
@ -32,7 +42,7 @@ pub(super) struct Old {
} }
impl Old { impl Old {
pub(super) fn open(db: sled::Db) -> anyhow::Result<Self> { pub(super) fn open(db: sled::Db) -> color_eyre::Result<Self> {
Ok(Self { Ok(Self {
alias_tree: db.open_tree("alias")?, alias_tree: db.open_tree("alias")?,
filename_tree: db.open_tree("filename")?, filename_tree: db.open_tree("filename")?,
@ -44,7 +54,7 @@ impl Old {
}) })
} }
pub(super) fn setting(&self, key: &[u8]) -> anyhow::Result<Option<sled::IVec>> { pub(super) fn setting(&self, key: &[u8]) -> color_eyre::Result<Option<sled::IVec>> {
Ok(self.settings_tree.get(key)?) Ok(self.settings_tree.get(key)?)
} }
@ -55,11 +65,14 @@ impl Old {
.filter_map(|res| res.ok()) .filter_map(|res| res.ok())
} }
pub(super) fn details(&self, hash: &sled::IVec) -> anyhow::Result<Vec<(sled::IVec, Details)>> { pub(super) fn details(
&self,
hash: &sled::IVec,
) -> color_eyre::Result<Vec<(sled::IVec, Details)>> {
let filename = self let filename = self
.main_tree .main_tree
.get(hash)? .get(hash)?
.ok_or_else(|| anyhow::anyhow!("missing filename"))?; .ok_or(OldDbError("Missing filename"))?;
let filename = String::from_utf8_lossy(&filename); let filename = String::from_utf8_lossy(&filename);
@ -81,22 +94,26 @@ impl Old {
.collect()) .collect())
} }
pub(super) fn main_identifier(&self, hash: &sled::IVec) -> anyhow::Result<sled::IVec> { pub(super) fn main_identifier(&self, hash: &sled::IVec) -> color_eyre::Result<sled::IVec> {
let filename = self let filename = self
.main_tree .main_tree
.get(hash)? .get(hash)?
.ok_or_else(|| anyhow::anyhow!("Missing filename"))?; .ok_or(OldDbError("Missing filename"))?;
self.identifier_tree Ok(self
.identifier_tree
.get(filename)? .get(filename)?
.ok_or_else(|| anyhow::anyhow!("Missing identifier")) .ok_or(OldDbError("Missing identifier"))?)
} }
pub(super) fn variants(&self, hash: &sled::IVec) -> anyhow::Result<Vec<(PathBuf, sled::IVec)>> { pub(super) fn variants(
&self,
hash: &sled::IVec,
) -> color_eyre::Result<Vec<(PathBuf, sled::IVec)>> {
let filename = self let filename = self
.main_tree .main_tree
.get(hash)? .get(hash)?
.ok_or_else(|| anyhow::anyhow!("Missing filename"))?; .ok_or(OldDbError("Missing filename"))?;
let filename_string = String::from_utf8_lossy(&filename); let filename_string = String::from_utf8_lossy(&filename);
@ -126,11 +143,11 @@ impl Old {
pub(super) fn motion_identifier( pub(super) fn motion_identifier(
&self, &self,
hash: &sled::IVec, hash: &sled::IVec,
) -> anyhow::Result<Option<sled::IVec>> { ) -> color_eyre::Result<Option<sled::IVec>> {
let filename = self let filename = self
.main_tree .main_tree
.get(hash)? .get(hash)?
.ok_or_else(|| anyhow::anyhow!("Missing filename"))?; .ok_or(OldDbError("Missing filename"))?;
let filename_string = String::from_utf8_lossy(&filename); let filename_string = String::from_utf8_lossy(&filename);
@ -151,7 +168,7 @@ impl Old {
.collect() .collect()
} }
pub(super) fn delete_token(&self, alias: &Alias) -> anyhow::Result<Option<DeleteToken>> { pub(super) fn delete_token(&self, alias: &Alias) -> color_eyre::Result<Option<DeleteToken>> {
let key = format!("{}/delete", alias); let key = format!("{}/delete", alias);
if let Some(ivec) = self.alias_tree.get(key)? { if let Some(ivec) = self.alias_tree.get(key)? {

View file

@ -122,6 +122,9 @@ impl Store for ObjectStore {
let request_span = tracing::info_span!(parent: None, "Get Object"); let request_span = tracing::info_span!(parent: None, "Get Object");
// NOTE: isolating reqwest in it's own span is to prevent the request's span from getting
// smuggled into a long-lived task. Unfortunately, I am unable to create a minimal
// reproduction of this problem so I can't open a bug about it.
let request = request_span.in_scope(|| { let request = request_span.in_scope(|| {
Client::request( Client::request(
&self.client, &self.client,