@@ -574,25 +574,32 @@ impl Processor {
574574 self . span . error = 1 ;
575575
576576 if let Some ( m) = message {
577+ let decoded_message = base64_to_string ( m) . unwrap_or_else ( |_| {
578+ debug ! ( "Error message header may not be encoded, setting as is" ) ;
579+ m. to_string ( )
580+ } ) ;
581+
577582 self . span
578583 . meta
579- . insert ( String :: from ( "error.msg" ) , m . to_string ( ) ) ;
584+ . insert ( String :: from ( "error.msg" ) , decoded_message ) ;
580585 }
581586
582587 if let Some ( t) = r#type {
588+ let decoded_type = base64_to_string ( t) . unwrap_or_else ( |_| {
589+ debug ! ( "Error type header may not be encoded, setting as is" ) ;
590+ t. to_string ( )
591+ } ) ;
592+
583593 self . span
584594 . meta
585- . insert ( String :: from ( "error.type" ) , t . to_string ( ) ) ;
595+ . insert ( String :: from ( "error.type" ) , decoded_type ) ;
586596 }
587597
588598 if let Some ( s) = stack {
589- let decoded_stack = match base64_to_string ( s) {
590- Ok ( decoded) => decoded,
591- Err ( e) => {
592- debug ! ( "Failed to decode error stack: {e}" ) ;
593- s. to_string ( )
594- }
595- } ;
599+ let decoded_stack = base64_to_string ( s) . unwrap_or_else ( |e| {
600+ debug ! ( "Failed to decode error stack: {e}" ) ;
601+ s. to_string ( )
602+ } ) ;
596603
597604 self . span
598605 . meta
@@ -607,3 +614,102 @@ impl Processor {
607614 self . enhanced_metrics . increment_oom_metric ( ) ;
608615 }
609616}
617+
618+ #[ cfg( test) ]
619+ mod tests {
620+ use super :: * ;
621+ use crate :: LAMBDA_RUNTIME_SLUG ;
622+ use base64:: { engine:: general_purpose:: STANDARD , Engine } ;
623+ use dogstatsd:: aggregator:: Aggregator ;
624+ use dogstatsd:: metric:: EMPTY_TAGS ;
625+
626+ fn setup ( ) -> Processor {
627+ let aws_config = AwsConfig {
628+ region : "us-east-1" . into ( ) ,
629+ aws_access_key_id : "***" . into ( ) ,
630+ aws_secret_access_key : "***" . into ( ) ,
631+ aws_session_token : "***" . into ( ) ,
632+ function_name : "test-function" . into ( ) ,
633+ sandbox_init_time : Instant :: now ( ) ,
634+ } ;
635+
636+ let config = Arc :: new ( config:: Config {
637+ service : Some ( "test-service" . to_string ( ) ) ,
638+ tags : Some ( "test:tags" . to_string ( ) ) ,
639+ ..config:: Config :: default ( )
640+ } ) ;
641+
642+ let tags_provider = Arc :: new ( provider:: Provider :: new (
643+ Arc :: clone ( & config) ,
644+ LAMBDA_RUNTIME_SLUG . to_string ( ) ,
645+ & HashMap :: from ( [ ( "function_arn" . to_string ( ) , "test-arn" . to_string ( ) ) ] ) ,
646+ ) ) ;
647+
648+ let metrics_aggregator = Arc :: new ( Mutex :: new (
649+ Aggregator :: new ( EMPTY_TAGS , 1024 ) . expect ( "failed to create aggregator" ) ,
650+ ) ) ;
651+
652+ Processor :: new ( tags_provider, config, & aws_config, metrics_aggregator)
653+ }
654+
655+ #[ test]
656+ fn test_set_span_error_from_base64_encoded_headers ( ) {
657+ let mut p = setup ( ) ;
658+ let mut headers = HashMap :: < String , String > :: new ( ) ;
659+
660+ let error_message = "Error message" ;
661+ let error_type = "System.Exception" ;
662+ let error_stack =
663+ "System.Exception: Error message \n at TestFunction.Handle(ILambdaContext context)" ;
664+
665+ headers. insert ( DATADOG_INVOCATION_ERROR_KEY . into ( ) , "true" . into ( ) ) ;
666+ headers. insert (
667+ DATADOG_INVOCATION_ERROR_MESSAGE_KEY . into ( ) ,
668+ STANDARD . encode ( error_message) ,
669+ ) ;
670+ headers. insert (
671+ DATADOG_INVOCATION_ERROR_TYPE_KEY . into ( ) ,
672+ STANDARD . encode ( error_type) ,
673+ ) ;
674+ headers. insert (
675+ DATADOG_INVOCATION_ERROR_STACK_KEY . into ( ) ,
676+ STANDARD . encode ( error_stack) ,
677+ ) ;
678+
679+ p. set_span_error_from_headers ( headers) ;
680+
681+ assert_eq ! ( p. span. error, 1 ) ;
682+ assert_eq ! ( p. span. meta[ "error.msg" ] , error_message) ;
683+ assert_eq ! ( p. span. meta[ "error.type" ] , error_type) ;
684+ assert_eq ! ( p. span. meta[ "error.stack" ] , error_stack) ;
685+ }
686+
687+ #[ test]
688+ fn test_set_span_error_from_non_encoded_headers ( ) {
689+ let mut p = setup ( ) ;
690+ let mut headers = HashMap :: < String , String > :: new ( ) ;
691+
692+ let error_message = "Error message" ;
693+ let error_type = "System.Exception" ;
694+ let error_stack =
695+ "System.Exception: Error message \n at TestFunction.Handle(ILambdaContext context)" ;
696+
697+ headers. insert ( DATADOG_INVOCATION_ERROR_KEY . into ( ) , "true" . into ( ) ) ;
698+ headers. insert (
699+ DATADOG_INVOCATION_ERROR_MESSAGE_KEY . into ( ) ,
700+ error_message. into ( ) ,
701+ ) ;
702+ headers. insert ( DATADOG_INVOCATION_ERROR_TYPE_KEY . into ( ) , error_type. into ( ) ) ;
703+ headers. insert (
704+ DATADOG_INVOCATION_ERROR_STACK_KEY . into ( ) ,
705+ error_stack. into ( ) ,
706+ ) ;
707+
708+ p. set_span_error_from_headers ( headers) ;
709+
710+ assert_eq ! ( p. span. error, 1 ) ;
711+ assert_eq ! ( p. span. meta[ "error.msg" ] , error_message) ;
712+ assert_eq ! ( p. span. meta[ "error.type" ] , error_type) ;
713+ assert_eq ! ( p. span. meta[ "error.stack" ] , error_stack) ;
714+ }
715+ }
0 commit comments