node-stack-trace.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /**
  2. * Does this filename look like it's part of the app code?
  3. */
  4. function filenameIsInApp(filename, isNative = false) {
  5. const isInternal =
  6. isNative ||
  7. (filename &&
  8. // It's not internal if it's an absolute linux path
  9. !filename.startsWith('/') &&
  10. // It's not internal if it's an absolute windows path
  11. !filename.match(/^[A-Z]:/) &&
  12. // It's not internal if the path is starting with a dot
  13. !filename.startsWith('.') &&
  14. // It's not internal if the frame has a protocol. In node, this is usually the case if the file got pre-processed with a bundler like webpack
  15. !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//)); // Schema from: https://stackoverflow.com/a/3641782
  16. // in_app is all that's not an internal Node function or a module within node_modules
  17. // note that isNative appears to return true even for node core libraries
  18. // see https://github.com/getsentry/raven-node/issues/176
  19. return !isInternal && filename !== undefined && !filename.includes('node_modules/');
  20. }
  21. /** Node Stack line parser */
  22. // eslint-disable-next-line complexity
  23. function node(getModule) {
  24. const FILENAME_MATCH = /^\s*[-]{4,}$/;
  25. const FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
  26. // eslint-disable-next-line complexity
  27. return (line) => {
  28. const lineMatch = line.match(FULL_MATCH);
  29. if (lineMatch) {
  30. let object;
  31. let method;
  32. let functionName;
  33. let typeName;
  34. let methodName;
  35. if (lineMatch[1]) {
  36. functionName = lineMatch[1];
  37. let methodStart = functionName.lastIndexOf('.');
  38. if (functionName[methodStart - 1] === '.') {
  39. methodStart--;
  40. }
  41. if (methodStart > 0) {
  42. object = functionName.slice(0, methodStart);
  43. method = functionName.slice(methodStart + 1);
  44. const objectEnd = object.indexOf('.Module');
  45. if (objectEnd > 0) {
  46. functionName = functionName.slice(objectEnd + 1);
  47. object = object.slice(0, objectEnd);
  48. }
  49. }
  50. typeName = undefined;
  51. }
  52. if (method) {
  53. typeName = object;
  54. methodName = method;
  55. }
  56. if (method === '<anonymous>') {
  57. methodName = undefined;
  58. functionName = undefined;
  59. }
  60. if (functionName === undefined) {
  61. methodName = methodName || '<anonymous>';
  62. functionName = typeName ? `${typeName}.${methodName}` : methodName;
  63. }
  64. let filename = lineMatch[2] && lineMatch[2].startsWith('file://') ? lineMatch[2].slice(7) : lineMatch[2];
  65. const isNative = lineMatch[5] === 'native';
  66. // If it's a Windows path, trim the leading slash so that `/C:/foo` becomes `C:/foo`
  67. if (filename && filename.match(/\/[A-Z]:/)) {
  68. filename = filename.slice(1);
  69. }
  70. if (!filename && lineMatch[5] && !isNative) {
  71. filename = lineMatch[5];
  72. }
  73. return {
  74. filename,
  75. module: getModule ? getModule(filename) : undefined,
  76. function: functionName,
  77. lineno: parseInt(lineMatch[3], 10) || undefined,
  78. colno: parseInt(lineMatch[4], 10) || undefined,
  79. in_app: filenameIsInApp(filename, isNative),
  80. };
  81. }
  82. if (line.match(FILENAME_MATCH)) {
  83. return {
  84. filename: line,
  85. };
  86. }
  87. return undefined;
  88. };
  89. }
  90. export { filenameIsInApp, node };
  91. //# sourceMappingURL=node-stack-trace.js.map