[UPdate] Add error boundary.

This commit is contained in:
Sakamoto Shiina
2025-04-10 21:47:18 +09:00
parent 7e637b795d
commit 2157d5952c
11 changed files with 408 additions and 45 deletions

78
map-stack.js Normal file
View File

@@ -0,0 +1,78 @@
#!/usr/bin/env node
// 使用例: node map-stack.js
// カレントディレクトリの error.txt を読み込み、各エラーフレームから
// 対応するソースマップdist/assets/ 以下の *.js.mapを用いて元の位置情報を出力する
import fs from "fs";
import path from "path";
import { SourceMapConsumer } from "source-map";
// 各スタックフレームにマッチする正規表現
const FRAME_REGEX = /^\s*at\s+(.*?)\s+\((.*):(\d+):(\d+)\)$/;
// スタックトレースのパース関数
const parseStackTrace = (text) => {
return text
.split(/\r?\n/)
.map((line) => {
const match = line.match(FRAME_REGEX);
if (match) {
return {
original: line,
functionName: match[1],
file: match[2],
line: Number(match[3]),
column: Number(match[4])
};
} else {
return { original: line };
}
});
};
// エラースタックをソースマップから逆引きする関数(位置情報のみを表示)
const mapStackTrace = async () => {
const errorTxtPath = path.resolve(process.cwd(), "error.txt");
const stackTraceText = fs.readFileSync(errorTxtPath, "utf8");
const frames = parseStackTrace(stackTraceText);
const consumerMap = new Map();
const mappedFrames = await Promise.all(frames.map(async (frame) => {
if (frame.file && frame.line && frame.column) {
const relativeFile = frame.file.replace(/^\//, ""); // 例: "assets/main-Td8-sruo.js"
const mapFilePath = path.resolve(process.cwd(), "dist", relativeFile + ".map");
let consumer = consumerMap.get(mapFilePath);
if (!consumer) {
const rawSourceMap = fs.readFileSync(mapFilePath, "utf8");
consumer = await new SourceMapConsumer(rawSourceMap);
consumerMap.set(mapFilePath, consumer);
}
const pos = consumer.originalPositionFor({
line: frame.line,
column: frame.column
});
if (pos && pos.source && pos.line != null && pos.column != null) {
return ` at ${frame.functionName} (${pos.source}:${pos.line}:${pos.column})`;
} else {
return frame.original;
}
} else {
return frame.original;
}
}));
consumerMap.forEach((consumer) => consumer.destroy());
return mappedFrames.join("\n");
};
mapStackTrace()
.then((mapped) => {
console.log("--- Mapped Stack Trace ---");
console.log(mapped);
})
.catch((err) => {
console.error(err);
process.exit(1);
});