Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Make more errors use ReportableError trait #632

Merged
merged 20 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d7150e4
feat: Make more errors use ReportableError trait
jrconlin Feb 21, 2024
4af45fa
f clippy
jrconlin Feb 22, 2024
b80ef6c
Merge branch 'master' of github.com:mozilla-services/autopush-rs into…
jrconlin Feb 22, 2024
d8455a5
f merge fix
jrconlin Feb 22, 2024
d36a4a6
Merge branch 'master' of github.com:mozilla-services/autopush-rs into…
jrconlin Feb 22, 2024
3c7fd58
Merge branch 'master' into bug/sync-4145-extras
jrconlin Feb 23, 2024
516e3f9
Merge branch 'master' into bug/sync-4145-extras
jrconlin Feb 26, 2024
92166ad
Merge branch 'master' into bug/sync-4145-extras
jrconlin Mar 7, 2024
f7f63dd
Merge branch 'master' of github.com:mozilla-services/autopush-rs into…
jrconlin Apr 10, 2024
038c8fc
Merge branch 'bug/sync-4145-extras' of github.com:mozilla-services/au…
jrconlin Apr 10, 2024
794730a
Merge branch 'master' of github.com:mozilla-services/autopush-rs into…
jrconlin Apr 19, 2024
00f0097
Merge branch 'master' into bug/sync-4145-extras
jrconlin May 6, 2024
9a103fa
Merge branch 'master' into bug/sync-4145-extras
pjenvey May 13, 2024
464d3e8
f r's
jrconlin May 14, 2024
f4cfd5e
Merge branch 'bug/sync-4145-extras' of github.com:mozilla-services/au…
jrconlin May 14, 2024
63c0f28
Merge branch 'master' of github.com:mozilla-services/autopush-rs into…
jrconlin May 15, 2024
18ae9d4
f fixup APNS errors
jrconlin May 15, 2024
780e9d2
f r's
jrconlin May 20, 2024
b4fb194
f r's (missed one)
jrconlin May 20, 2024
eefddab
Merge branch 'master' of github.com:mozilla-services/autopush-rs into…
jrconlin May 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions autoendpoint/src/routers/apns/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::error::ApiErrorKind;
use crate::routers::RouterError;
use actix_web::http::StatusCode;
use autopush_common::errors::ReportableError;
use backtrace::Backtrace;
use std::io;

/// Errors that may occur in the Apple Push Notification Service router
Expand Down Expand Up @@ -86,3 +88,31 @@ impl From<ApnsError> for ApiErrorKind {
ApiErrorKind::Router(RouterError::Apns(e))
}
}

impl ReportableError for ApnsError {
fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
None
}

jrconlin marked this conversation as resolved.
Show resolved Hide resolved
fn backtrace(&self) -> Option<&Backtrace> {
None
}

fn is_sentry_event(&self) -> bool {
matches!(
self,
ApnsError::SizeLimit(_) | ApnsError::Unregistered | ApnsError::ApnsUpstream(_)
jrconlin marked this conversation as resolved.
Show resolved Hide resolved
)
}

fn metric_label(&self) -> Option<&'static str> {
match &self {
ApnsError::SizeLimit(_) => Some("notification.bridge.error.apns.oversized"),
_ => None,
}
}

fn extras(&self) -> Vec<(&str, String)> {
vec![]
}
jrconlin marked this conversation as resolved.
Show resolved Hide resolved
}
49 changes: 42 additions & 7 deletions autoendpoint/src/routers/fcm/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::error::ApiErrorKind;
use crate::routers::RouterError;

use autopush_common::errors::ReportableError;
use backtrace::Backtrace;
use reqwest::StatusCode;

/// Errors that may occur in the Firebase Cloud Messaging router
Expand Down Expand Up @@ -71,9 +74,47 @@ impl FcmError {
| FcmError::NoOAuthToken => None,
}
}
}

pub fn extras(&self) -> Vec<(&str, String)> {
impl From<FcmError> for ApiErrorKind {
fn from(e: FcmError) -> Self {
ApiErrorKind::Router(RouterError::Fcm(e))
}
}

impl ReportableError for FcmError {
fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
None
}

jrconlin marked this conversation as resolved.
Show resolved Hide resolved
fn backtrace(&self) -> Option<&Backtrace> {
None
}

fn is_sentry_event(&self) -> bool {
matches!(
&self,
FcmError::InvalidAppId(_)
| FcmError::NoAppId
| FcmError::EmptyResponse(_)
| FcmError::InvalidResponse(_, _, _)
)
jrconlin marked this conversation as resolved.
Show resolved Hide resolved
}

fn metric_label(&self) -> Option<&'static str> {
match &self {
FcmError::InvalidAppId(_) | FcmError::NoAppId => {
Some("notification.bridge.error.fcm.badappid")
}
_ => None,
}
}

fn extras(&self) -> Vec<(&str, String)> {
match self {
FcmError::InvalidAppId(appid) => {
vec![("app_id", appid.to_string())]
}
FcmError::EmptyResponse(status) => {
vec![("status", status.to_string())]
}
Expand All @@ -84,9 +125,3 @@ impl FcmError {
}
}
}

impl From<FcmError> for ApiErrorKind {
fn from(e: FcmError) -> Self {
ApiErrorKind::Router(RouterError::Fcm(e))
}
}
56 changes: 31 additions & 25 deletions autoendpoint/src/routers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,38 +162,28 @@ impl RouterError {
RouterError::Upstream { .. } => None,
}
}
}

pub fn metric_label(&self) -> Option<&'static str> {
// NOTE: Some metrics are emitted for other Errors via handle_error
// callbacks, whereas some are emitted via this method. These 2 should
// be consoliated: https://mozilla-hub.atlassian.net/browse/SYNC-3695
let err = match self {
RouterError::Adm(AdmError::InvalidProfile | AdmError::NoProfile) => {
"notification.bridge.error.adm.profile"
}
RouterError::Apns(ApnsError::SizeLimit(_)) => {
"notification.bridge.error.apns.oversized"
}
RouterError::Fcm(FcmError::InvalidAppId(_) | FcmError::NoAppId) => {
"notification.bridge.error.fcm.badappid"
}
RouterError::TooMuchData(_) => "notification.bridge.error.too_much_data",
RouterError::SaveDb(e) => e.metric_label().unwrap_or_default(),
_ => "",
};
if !err.is_empty() {
return Some(err);
impl ReportableError for RouterError {
fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
match &self {
RouterError::Apns(e) => Some(e),
RouterError::Fcm(e) => Some(e),
RouterError::SaveDb(e) => Some(e),
_ => None,
}
}

fn backtrace(&self) -> Option<&backtrace::Backtrace> {
None
}

pub fn is_sentry_event(&self) -> bool {
fn is_sentry_event(&self) -> bool {
match self {
RouterError::Adm(e) => !matches!(e, AdmError::InvalidProfile | AdmError::NoProfile),
// apns handle_error emits a metric for ApnsError::Unregistered
RouterError::Apns(ApnsError::SizeLimit(_))
| RouterError::Apns(ApnsError::Unregistered) => false,
RouterError::Fcm(e) => !matches!(e, FcmError::InvalidAppId(_) | FcmError::NoAppId),
RouterError::Apns(e) => e.is_sentry_event(),
RouterError::Fcm(e) => e.is_sentry_event(),
// common handle_error emits metrics for these
RouterError::Authentication
| RouterError::GCMAuthentication
Expand All @@ -207,8 +197,24 @@ impl RouterError {
}
}

pub fn extras(&self) -> Vec<(&str, String)> {
fn metric_label(&self) -> Option<&'static str> {
// NOTE: Some metrics are emitted for other Errors via handle_error
// callbacks, whereas some are emitted via this method. These 2 should
// be consoliated: https://mozilla-hub.atlassian.net/browse/SYNC-3695
match self {
RouterError::Adm(AdmError::InvalidProfile | AdmError::NoProfile) => {
Some("notification.bridge.error.adm.profile")
}
RouterError::Apns(e) => e.metric_label(),
RouterError::Fcm(e) => e.metric_label(),
RouterError::TooMuchData(_) => Some("notification.bridge.error.too_much_data"),
_ => None,
}
}

fn extras(&self) -> Vec<(&str, String)> {
match &self {
RouterError::Apns(e) => e.extras(),
RouterError::Fcm(e) => e.extras(),
RouterError::SaveDb(e) => e.extras(),
_ => vec![],
Expand Down
24 changes: 13 additions & 11 deletions autoendpoint/src/routes/health.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Health and Dockerflow routes
use std::collections::HashMap;
use std::thread;

use actix_web::{
Expand All @@ -17,18 +18,19 @@ use crate::server::AppState;
pub async fn health_route(state: Data<AppState>) -> Json<serde_json::Value> {
let router_health = interpret_table_health(state.db.router_table_exists().await);
let message_health = interpret_table_health(state.db.message_table_exists().await);
let mut routers: HashMap<&str, bool> = HashMap::new();
routers.insert("adm", state.adm_router.active());
routers.insert("apns", state.apns_router.active());
routers.insert("fcm", state.fcm_router.active());

Json(json!({
"status": "OK",
"version": env!("CARGO_PKG_VERSION"),
"router_table": router_health,
"message_table": message_health,
"routers": {
"adm": state.adm_router.active(),
"apns": state.apns_router.active(),
"fcm": state.fcm_router.active(),
}
}))
let health = json!({
"status": "OK",
"version": env!("CARGO_PKG_VERSION"),
"router_table": router_health,
"message_table": message_health,
"routers": routers});

Json(health)
}

/// Convert the result of a DB health check to JSON
Expand Down
3 changes: 2 additions & 1 deletion autoendpoint/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use autopush_common::{

use crate::error::{ApiError, ApiErrorKind, ApiResult};
use crate::metrics;
use crate::routers::{adm::router::AdmRouter, apns::router::ApnsRouter, fcm::router::FcmRouter};
use crate::routers::adm::router::AdmRouter;
use crate::routers::{apns::router::ApnsRouter, fcm::router::FcmRouter};
use crate::routes::{
health::{health_route, lb_heartbeat_route, log_check, status_route, version_route},
registration::{
Expand Down
18 changes: 10 additions & 8 deletions autopush-common/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub enum ApcErrorKind {
#[error("Database Error: {0}")]
DatabaseError(String),

// TODO: option this.
// TODO: Feature flag this.
#[error("Rusoto Error: {0}")]
RusotoError(String),
}
Expand Down Expand Up @@ -167,13 +167,12 @@ impl ApcErrorKind {

pub fn metric_label(&self) -> Option<&'static str> {
// TODO: add labels for skipped stuff
let label = match self {
Self::PongTimeout => "pong_timeout",
Self::ExcessivePing => "excessive_ping",
Self::PayloadError(_) => "payload",
_ => return None,
};
Some(label)
match self {
Self::PongTimeout => Some("pong_timeout"),
Self::ExcessivePing => Some("excessive_ping"),
Self::PayloadError(_) => Some("payload"),
_ => None,
}
}
}

Expand Down Expand Up @@ -210,6 +209,9 @@ pub trait ReportableError: std::error::Error {
}

impl ReportableError for ApcError {
fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
None
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
None
}

fn backtrace(&self) -> Option<&Backtrace> {
Some(&self.backtrace)
}
Expand Down