1- use std:: { cell:: RefCell , collections:: BTreeMap , marker:: PhantomData , rc:: Rc , sync:: Arc } ;
1+ use std:: { cell:: RefCell , collections:: BTreeMap , env , marker:: PhantomData , rc:: Rc , sync:: Arc } ;
22
33use actix_web:: {
44 Error ,
@@ -15,13 +15,20 @@ use crate::{ReportableError, Taggable};
1515pub struct SentryWrapper < E > {
1616 metrics : Arc < StatsdClient > ,
1717 phantom : PhantomData < E > ,
18+ sentry_enabled : bool ,
19+ backtrace_enabled : bool ,
1820}
1921
2022impl < E > SentryWrapper < E > {
2123 pub fn new ( metrics : Arc < StatsdClient > ) -> Self {
24+ let sentry_enabled = env:: var ( "SENTRY_DSN" ) . is_ok_and ( |dsn| !dsn. is_empty ( ) ) ;
25+ let backtrace_enabled = env:: var ( "RUST_BACKTRACE" ) . is_ok_and ( |v| v == "1" || v == "full" ) ;
26+
2227 Self {
2328 metrics,
2429 phantom : PhantomData ,
30+ sentry_enabled,
31+ backtrace_enabled,
2532 }
2633 }
2734}
4350 service : Rc :: new ( RefCell :: new ( service) ) ,
4451 metrics : self . metrics . clone ( ) ,
4552 phantom : PhantomData ,
53+ sentry_enabled : self . sentry_enabled ,
54+ backtrace_enabled : self . backtrace_enabled ,
4655 } )
4756 }
4857}
@@ -52,6 +61,8 @@ pub struct SentryWrapperMiddleware<S, E> {
5261 service : Rc < RefCell < S > > ,
5362 metrics : Arc < StatsdClient > ,
5463 phantom : PhantomData < E > ,
64+ sentry_enabled : bool ,
65+ backtrace_enabled : bool ,
5566}
5667
5768impl < S , B , E > Service < ServiceRequest > for SentryWrapperMiddleware < S , E >
7788
7889 // get the tag information
7990 let metrics = self . metrics . clone ( ) ;
91+ let sentry_enabled = self . sentry_enabled ;
92+ let backtrace_enabled = self . backtrace_enabled ;
8093 let tags = sreq. get_tags ( ) ;
8194 let extras = sreq. get_extras ( ) ;
8295
@@ -99,12 +112,19 @@ where
99112 }
100113 } ;
101114 debug ! ( "Reporting error to Sentry (service error): {}" , error) ;
115+
102116 let mut event = event_from_actix_error :: < E > ( & error) ;
103117 // Add in the tags from the request
104118 event. tags . extend ( tags) ;
105119 event. extra . extend ( extras) ;
106- let event_id = hub. capture_event ( event) ;
107- trace ! ( "event_id = {}" , event_id) ;
120+
121+ if sentry_enabled {
122+ let event_id = hub. capture_event ( event) ;
123+ trace ! ( "event_id = {}" , event_id) ;
124+ } else {
125+ // log if Sentry is not configured
126+ log_event :: < E > ( & event, & error, backtrace_enabled) ;
127+ }
108128 return Err ( error) ;
109129 }
110130 } ;
@@ -118,9 +138,16 @@ where
118138 return Ok ( response) ;
119139 }
120140 debug ! ( "Reporting error to Sentry (response error): {}" , error) ;
141+
121142 let event = event_from_actix_error :: < E > ( error) ;
122- let event_id = hub. capture_event ( event) ;
123- trace ! ( "event_id = {}" , event_id) ;
143+
144+ if sentry_enabled {
145+ let event_id = hub. capture_event ( event) ;
146+ trace ! ( "event_id = {}" , event_id) ;
147+ } else {
148+ // log if Sentry is not configured
149+ log_event :: < E > ( & event, error, backtrace_enabled) ;
150+ }
124151 }
125152 Ok ( response)
126153 }
@@ -266,3 +293,42 @@ pub fn exception_from_reportable_error(err: &dyn ReportableError) -> sentry::pro
266293 ..Default :: default ( )
267294 }
268295}
296+
297+ /// Log the error event instead when Sentry is not configured.
298+ fn log_event < E > (
299+ event : & sentry:: protocol:: Event < ' static > ,
300+ error : & actix_web:: Error ,
301+ backtrace_enabled : bool ,
302+ ) where
303+ E : ReportableError + actix_web:: ResponseError + ' static ,
304+ {
305+ let first_exception = event. exception . last ( ) ;
306+ let error_type = first_exception. map_or ( "UnknownError" , |e| e. ty . as_str ( ) ) ;
307+ let error_value = first_exception
308+ . and_then ( |e| e. value . as_deref ( ) )
309+ . unwrap_or ( "No error message" ) ;
310+
311+ let backtrace = if backtrace_enabled {
312+ error
313+ . as_error :: < E > ( )
314+ . and_then ( |e| e. backtrace ( ) )
315+ . map ( |bt| format ! ( "\n {bt:?}" ) )
316+ . unwrap_or_default ( )
317+ } else {
318+ String :: new ( )
319+ } ;
320+
321+ error ! (
322+ "{}{}" , error_value, backtrace;
323+ "error_type" => error_type,
324+ "tags" => ?event. tags,
325+ "extra" => ?event. extra,
326+ "url" => event. request. as_ref( )
327+ . and_then( |r| r. url. as_ref( ) )
328+ . map( |u| u. to_string( ) )
329+ . unwrap_or_default( ) ,
330+ "method" => event. request. as_ref( )
331+ . and_then( |r| r. method. as_deref( ) )
332+ . unwrap_or( "" ) ,
333+ ) ;
334+ }
0 commit comments