(line: string)
| 68 | }; |
| 69 | |
| 70 | const parseStackFrame = (line: string): StackFrame => { |
| 71 | const trimmed = line.trim(); |
| 72 | |
| 73 | // Pattern: at functionName (filePath:line:column) |
| 74 | const withParensMatch = trimmed.match(STACK_FRAME_WITH_PARENS_REGEX); |
| 75 | if (withParensMatch) { |
| 76 | const [, functionName, filePath, lineNum, colNum] = withParensMatch; |
| 77 | const isInternal = |
| 78 | filePath.includes("node_modules") || |
| 79 | filePath.startsWith("node:") || |
| 80 | filePath.includes("internal/"); |
| 81 | return { |
| 82 | columnNumber: colNum ? Number.parseInt(colNum, 10) : null, |
| 83 | filePath: filePath ?? null, |
| 84 | functionName: functionName ?? null, |
| 85 | isInternal, |
| 86 | lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null, |
| 87 | raw: trimmed, |
| 88 | }; |
| 89 | } |
| 90 | |
| 91 | // Pattern: at filePath:line:column (no function name) |
| 92 | const withoutFnMatch = trimmed.match(STACK_FRAME_WITHOUT_FN_REGEX); |
| 93 | if (withoutFnMatch) { |
| 94 | const [, filePath, lineNum, colNum] = withoutFnMatch; |
| 95 | const isInternal = |
| 96 | (filePath?.includes("node_modules") ?? false) || |
| 97 | (filePath?.startsWith("node:") ?? false) || |
| 98 | (filePath?.includes("internal/") ?? false); |
| 99 | return { |
| 100 | columnNumber: colNum ? Number.parseInt(colNum, 10) : null, |
| 101 | filePath: filePath ?? null, |
| 102 | functionName: null, |
| 103 | isInternal, |
| 104 | lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null, |
| 105 | raw: trimmed, |
| 106 | }; |
| 107 | } |
| 108 | |
| 109 | // Fallback: unparseable line |
| 110 | return { |
| 111 | columnNumber: null, |
| 112 | filePath: null, |
| 113 | functionName: null, |
| 114 | isInternal: trimmed.includes("node_modules") || trimmed.includes("node:"), |
| 115 | lineNumber: null, |
| 116 | raw: trimmed, |
| 117 | }; |
| 118 | }; |
| 119 | |
| 120 | const parseStackTrace = (trace: string): ParsedStackTrace => { |
| 121 | const lines = trace.split("\n").filter((line) => line.trim()); |
nothing calls this directly
no outgoing calls
no test coverage detected