Skip to content

Commit beb8bf6

Browse files
Decode error message and error type (#500)
* decode error message and type * added unit tests * format fixes * fix debug log message
1 parent e792b63 commit beb8bf6

File tree

1 file changed

+115
-9
lines changed

1 file changed

+115
-9
lines changed

bottlecap/src/lifecycle/invocation/processor.rs

Lines changed: 115 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)