From 5421f58182b9061afaec0d5265dc3d1045d44633 Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Tue, 31 Oct 2023 12:04:01 -0700 Subject: [PATCH] feat: further detect common io errors in megaphone's updater (#492) return SMError's backtrace for WSError (for now) SYNC-3978 --- Cargo.lock | 1 + autoconnect/autoconnect-common/Cargo.toml | 1 + .../autoconnect-common/src/megaphone.rs | 30 ++++++++++++++++++- autoconnect/autoconnect-ws/src/error.rs | 7 ++++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d52b3d0e7..22f512b18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -576,6 +576,7 @@ dependencies = [ "cadence", "futures 0.3.28", "futures-locks 0.7.1", + "hyper 0.14.27", "reqwest 0.11.22", "sentry", "serde", diff --git a/autoconnect/autoconnect-common/Cargo.toml b/autoconnect/autoconnect-common/Cargo.toml index ec7375775..8c3eaba1c 100644 --- a/autoconnect/autoconnect-common/Cargo.toml +++ b/autoconnect/autoconnect-common/Cargo.toml @@ -11,6 +11,7 @@ actix-web.workspace = true cadence.workspace = true futures.workspace = true futures-locks.workspace = true +hyper.workspace = true reqwest.workspace = true tokio.workspace = true sentry.workspace = true diff --git a/autoconnect/autoconnect-common/src/megaphone.rs b/autoconnect/autoconnect-common/src/megaphone.rs index fe140d0ab..654a26505 100644 --- a/autoconnect/autoconnect-common/src/megaphone.rs +++ b/autoconnect/autoconnect-common/src/megaphone.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, sync::Arc, time::Duration}; +use std::{collections::HashMap, error::Error, io, sync::Arc, time::Duration}; use actix_web::rt; use cadence::{CountedExt, StatsdClient}; @@ -53,6 +53,8 @@ fn report_updater_error(metrics: &Arc, err: reqwest::Error) { "timeout" } else if err.is_connect() { "connect" + } else if is_io(&err) { + "io" } else { "unknown" }; @@ -91,3 +93,29 @@ async fn updater( } Ok(()) } + +/// Determine if a source of [reqwest::Error] was a [hyper::Error] Io Error +fn is_io(err: &reqwest::Error) -> bool { + let mut source = err.source(); + while let Some(err) = source { + if let Some(hyper_err) = err.downcast_ref::() { + if is_hyper_io(hyper_err) { + return true; + } + } + source = err.source(); + } + false +} + +/// Determine if a source of [hyper::Error] was an [io::Error] +fn is_hyper_io(err: &hyper::Error) -> bool { + let mut source = err.source(); + while let Some(err) = source { + if err.downcast_ref::().is_some() { + return true; + } + source = err.source(); + } + false +} diff --git a/autoconnect/autoconnect-ws/src/error.rs b/autoconnect/autoconnect-ws/src/error.rs index c04b97d54..ff43c979c 100644 --- a/autoconnect/autoconnect-ws/src/error.rs +++ b/autoconnect/autoconnect-ws/src/error.rs @@ -73,7 +73,12 @@ impl WSError { impl ReportableError for WSError { fn backtrace(&self) -> Option<&Backtrace> { - self.backtrace.as_ref() + // XXX: dumb hack: return SMError's backtrace for now as our + // sentry::event_from_error doesn't capture it + match &self.kind { + WSErrorKind::SM(e) => e.backtrace(), + _ => self.backtrace.as_ref(), + } } fn is_sentry_event(&self) -> bool {