From 9ce2ad1454c0ab968416fb9513e36a8113af2266 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Thu, 1 Aug 2024 18:04:41 +0200 Subject: [PATCH] fix(js): Recognize more abs_paths as in-app (#1505) The original logic for deciding whether a JS frame should be in-app (seen at https://github.com/getsentry/sentry/blob/69ee8d0fcbff3494f2d2a6fb9fb59195fc49b575/src/sentry/lang/javascript/processor.py#L1573-L1603) is quite convoluted and difficult to understand. The `is_in_app` function reproduces it faithfully, but with some refactoring. In any case, for webpack, only file names beginning with `./` would be considered as in-app, but judging from examples that's too strict. Therefore we change the logic for webpack as follows: A file name is considered _not_ in-app if either of these is true: * It starts with `~/` (according to the documentation in the original Python version, this means it's "coming from node_modules"). * It contains `/node_modules/` as a substring. Otherwise it's considered in-app. --- crates/symbolicator-js/src/utils.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/symbolicator-js/src/utils.rs b/crates/symbolicator-js/src/utils.rs index f0aa85564..634a3c959 100644 --- a/crates/symbolicator-js/src/utils.rs +++ b/crates/symbolicator-js/src/utils.rs @@ -111,9 +111,17 @@ pub fn fixup_webpack_filename(filename: &str) -> String { } } +/// Returns whether the given abs_path and filename should be considered in-app. +/// +/// This function was originally a simplified (but semantically faithful) version of +/// . +/// For a version that preserves the original exactly (modulo Python -> Rust translation), see +/// `is_in_app_faithful`. pub fn is_in_app(abs_path: &str, filename: &str) -> Option { if abs_path.starts_with("webpack:") { - Some(filename.starts_with("./") && !filename.contains("/node_modules/")) + // This diverges from the original logic. Previously we would only consider + // a filename starting with `./` as in-app, but that seems to be overly strict. + Some(!filename.starts_with("~/") && !filename.contains("/node_modules/")) } else if abs_path.starts_with("app:") { Some(!NODE_MODULES_RE.is_match(filename)) } else if abs_path.contains("/node_modules/") { @@ -718,6 +726,20 @@ mod tests { assert_eq!(is_in_app(abs_path, filename), Some(true)); assert_eq!(is_in_app_faithful(abs_path, filename), Some(true)); + let abs_path = "webpack:///foo/bar/src/App.jsx"; + let filename = "foo/bar/src/App.jsx"; + + // Here we have a discrepancy because the behavior of `is_in_app` + // longer aligns with that of the original Python version. + assert_eq!(is_in_app(abs_path, filename), Some(true)); + assert_eq!(is_in_app_faithful(abs_path, filename), Some(false)); + + let abs_path = "webpack:///./foo/bar/App.tsx"; + let filename = "./foo/bar/src/App.jsx"; + + assert_eq!(is_in_app(abs_path, filename), Some(true)); + assert_eq!(is_in_app_faithful(abs_path, filename), Some(true)); + let abs_path = "webpack:///./node_modules/@sentry/browser/esm/helpers.js"; let filename = "./node_modules/@sentry/browser/esm/helpers.js";