Skip to content

Commit

Permalink
Shits and giggles: Manual error type with backtrace
Browse files Browse the repository at this point in the history
For some reaons I never got filenames and line numbers out of this, so
less useful than I was hoping.  I suspect I did something wrong though.
  • Loading branch information
Floris Bruynooghe committed Oct 16, 2020
1 parent b479052 commit a04b024
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 19 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ actix-web = { version = "0.7.19", features = ["tls"], default-features = false }
actix = "0.7.9"
anyhow = "1.0.32"
apple-crash-report-parser = "0.4.2"
backtrace = "0.3"
failure = "0.1.6"
thiserror = "1.0.20"
serde = { version = "1.0.101", features = ["derive", "rc"] }
Expand Down
105 changes: 86 additions & 19 deletions src/actors/objects/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::cmp;
use std::error::Error;
use std::fmt;
use std::fs;
use std::io::{self, Read, Seek, SeekFrom};
use std::path::Path;
Expand All @@ -7,12 +9,12 @@ use std::sync::Arc;
use std::time::Duration;

use ::sentry::{configure_scope, Hub};
use backtrace::Backtrace;
use futures::future::{FutureExt, TryFutureExt};
use futures01::{future, Future};
use symbolic::common::ByteView;
use symbolic::debuginfo::{self, Archive, Object};
use tempfile::tempfile_in;
use thiserror::Error;

use crate::actors::common::cache::{CacheItemRequest, CachePath, Cacher};
use crate::cache::{Cache, CacheKey, CacheStatus};
Expand All @@ -25,31 +27,96 @@ use crate::utils::objects;
use crate::utils::sentry::{SentryFutureExt, WriteSentryScope};

/// Errors happening while fetching objects.
#[derive(Debug, Error)]
pub enum ObjectError {
#[error("failed to download")]
Io(#[from] io::Error),
Io(io::Error, Backtrace),
Download(DownloadError),
Persisting(serde_json::Error),
NoTempDir,
Malformed,
Parsing(debuginfo::ObjectError),
Caching(Arc<ObjectError>),
Timeout,
}

#[error("failed to download")]
Download(#[from] DownloadError),
impl fmt::Display for ObjectError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ObjectError: ")?;
match self {
ObjectError::Io(_, _) => write!(f, "failed to download (I/O error)")?,
ObjectError::Download(_) => write!(f, "failed to download")?,
ObjectError::Persisting(_) => write!(f, "failed persisting data")?,
ObjectError::NoTempDir => write!(f, "unable to get directory for tempfiles")?,
ObjectError::Malformed => write!(f, "malformed object file")?,
ObjectError::Parsing(_) => write!(f, "failed to parse object")?,
ObjectError::Caching(_) => write!(f, "failed to look into cache")?,
ObjectError::Timeout => write!(f, "object download took too long")?,
}
if f.alternate() {
if let Some(ref source) = self.source() {
write!(f, "\n caused by: ")?;
fmt::Display::fmt(source, f)?;
}
}
Ok(())
}
}

#[error("failed persisting metadata")]
Persisting(#[from] serde_json::Error),
impl fmt::Debug for ObjectError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self)?;
match self {
ObjectError::Io(_, ref backtrace) => {
write!(f, "\n backtrace:\n{:?}", backtrace)?;
}
_ => (),
}
if f.alternate() {
if let Some(ref source) = self.source() {
write!(f, "\n caused by: ")?;
fmt::Debug::fmt(source, f)?;
}
}
Ok(())
}
}

#[error("unable to get directory for tempfiles")]
NoTempDir,
impl std::error::Error for ObjectError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ObjectError::Io(ref source, _) => Some(source),
ObjectError::Download(ref source) => Some(source),
ObjectError::Persisting(ref source) => Some(source),
ObjectError::NoTempDir => None,
ObjectError::Malformed => None,
ObjectError::Parsing(ref source) => Some(source),
ObjectError::Caching(ref source) => Some(source.as_ref()),
ObjectError::Timeout => None,
}
}
}

#[error("malformed object file")]
Malformed,
impl From<io::Error> for ObjectError {
fn from(source: io::Error) -> Self {
Self::Io(source, Backtrace::new())
}
}

#[error("failed to parse object")]
Parsing(#[from] debuginfo::ObjectError),
impl From<DownloadError> for ObjectError {
fn from(source: DownloadError) -> Self {
Self::Download(source)
}
}

#[error("failed to look into cache")]
Caching(#[source] Arc<ObjectError>),
impl From<serde_json::Error> for ObjectError {
fn from(source: serde_json::Error) -> Self {
Self::Persisting(source)
}
}

#[error("object download took too long")]
Timeout,
impl From<debuginfo::ObjectError> for ObjectError {
fn from(source: debuginfo::ObjectError) -> Self {
Self::Parsing(source)
}
}

/// This requests metadata of a single file at a specific path/url.
Expand Down Expand Up @@ -499,7 +566,7 @@ impl ObjectsActor {
let object = match response {
Ok(object) => object,
Err(e) => {
log::debug!("Failed to download: {}", LogError(e));
log::debug!("Failed to download: {:#?}", e);
return (3, *i);
}
};
Expand Down

0 comments on commit a04b024

Please sign in to comment.