当我的 React Native 应用程序出现错误时,打印到控制台的堆栈跟踪指向
index.bundle
而不是原始源代码(请参见下面的示例)。有没有办法配置 React Native 使用源映射以便日志正确显示?
此问题仅在从异步回调或渲染之外的其他内容引发错误时发生。如果我在组件内抛出错误,则该错误会在控制台中显示正确的堆栈跟踪。有趣的是,错误始终在 LogBox 中显示正确的堆栈跟踪。
我正在使用
react-native run-android
运行此程序并通过 Metro 查看日志。为了澄清,我试图让它适用于本地调试版本,而不是生产/发布版本。理想情况下,日志会在控制台中显示正确的堆栈,这样我就不必手动符号化它们或在 LogBox 中查找错误。
console.error 的结果示例:
Error: Connection closed
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.myapp.local&modulesOnly=false&runModule=true:261835:40)
at forEach (native)
at flushVolatile (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.myapp.local&modulesOnly=false&runModule=true:261833:33)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.myapp.local&modulesOnly=false&runModule=true:262065:20)
at apply (native)
提前谢谢您!
回答我自己的问题。我深入研究了 React-Native 代码,发现 LogBox 通过调用 Metro 开发服务器来表示堆栈跟踪。我没有复制这个逻辑,而是制作了下面与 LogBox 相关的黑客解决方案。我确信有更好的方法可以做到这一点,但它确实有效。
import { observe as observeLogBoxLogs, symbolicateLogNow } from 'react-native/Libraries/LogBox/Data/LogBoxData';
// LogBox keeps all logs that you have not viewed yet.
// When a new log comes in, we only want to print out the new ones.
let lastCount = 0;
observeLogBoxLogs(data => {
const logs = Array.from(data.logs);
const symbolicatedLogs = logs.filter(log => log.symbolicated.stack?.length);
for (let i = lastCount; i < symbolicatedLogs.length; i++) {
// use log instead of warn/error to prevent resending error to LogBox
console.log(formatLog(symbolicatedLogs[i]));
}
lastCount = symbolicatedLogs.length;
// Trigger symbolication on remaining logs because
// logs do not symbolicate until you click on LogBox
logs.filter(log => log.symbolicated.status === 'NONE').forEach(log => symbolicateLogNow(log));
});
function formatLog(log) {
const stackLines = (log.symbolicated.stack || [])
.filter(line => !line.collapse)
.map(line => ` at ${line.methodName} (${line.file}:${line.lineNumber}:${line.column})`)
.join('\n');
return `Error has been symbolicated\nError: ${log.message.content}\n${stackLines}`;
}
该错误在控制台中出现两次,第一次是原始版本,第二次是符号版本。这是现在日志输出的示例:
WARN Error: Connection closed
Error: Connection closed
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:334491:50)
at forEach (native)
at flushVolatile (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:334489:43)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:334721:30)
at call (native)
at emitNone (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:340110:33)
at emit (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:340191:23)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:339907:24)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:339889:30)
at apply (native)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:347770:25)
at drainQueue (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:347735:45)
at apply (native)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:31681:26)
at _callTimer (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:31605:17)
at callTimers (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:31801:19)
at apply (native)
at __callFunction (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:25085:36)
at anonymous (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:24813:31)
at __guard (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:25039:15)
at callFunctionReturnFlushedQueue (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.logtest.local&modulesOnly=false&runModule=true:24812:21)
LOG Error has been symbolicated
Error: Connection closed
at Object.keys.forEach$argument_0 (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:208:28)
at flushVolatile (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:206:4)
at stream.on$argument_1 (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:477:17)
at emitNone (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:6471:4)
at emit (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:6556:14)
at Duplexify.prototype._destroy (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:6239:2)
at process.nextTick$argument_0 (/Users/georgeflug/projects/logteste/node_modules/mqtt/dist/mqtt.js:6221:4)
at Item.prototype.run (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:13143:4)
at drainQueue (/Users/georgeflug/projects/logtest/node_modules/mqtt/dist/mqtt.js:13113:16)
如果您单击堆栈跟踪(例如在终端中),它会将您的 vscode 以及所有关联的文件拉到此位置吗?至少您可以在代码中找到问题所在?
这在 React Native 的生产版本中不适用于生产应用程序,出于性能和安全原因默认禁用符号化