使用源映射时以字符串形式获取堆栈跟踪?

538*_*MEO 5 javascript error-handling stack-trace node.js reactjs

为了尽可能多地从错误中获取信息,我想捕获堆栈跟踪以显示在浏览器控制台中,并将其发送到外部记录器服务。

console.error(myError)当浏览器正确解释源映射文件并且堆栈跟踪显示相关文件名时,第一种情况工作正常。

但是,当我尝试使用 获取堆栈跟踪作为字符串时(new Error()).stack,文件名不相关:

My Error
at applicationError (http://localhost:3000/static/js/main.chunk.js:29259:
at http://localhost:3000/static/js/main.chunk.js:1624:
at onError (http://localhost:3000/static/js/0.chunk.js:82415:3)
at apiCall (http://localhost:3000/static/js/0.chunk.js:82449:12)
at async http://localhost:3000/static/js/main.chunk.js:26165:21
at async App.componentWillMount (http://localhost:3000/static/js/main.chunk.js:246:5)
Run Code Online (Sandbox Code Playgroud)

如何获取“已解析”堆栈跟踪,以便将相关信息发送到我的记录器?

我已经看到了这些问题,但是,虽然这个问题乍一看似乎很相关,但没有一个回答我的问题:

Yuv*_*l.R 1

我遇到了同样的问题,最后,我找到了这个 npm 模块: https: //www.npmjs.com/package/sourcemapped-stacktrace

自述文件中的示例:

try {
  // break something
  bork();
} catch (e) {
  // pass e.stack to window.mapStackTrace
  window.mapStackTrace(e.stack, function(mappedStack) {
    // do what you want with mappedStack here
    console.log(mappedStack.join("\n"));
  }, {
    filter: function (line) {
      // process only sources containing `spec.js`
      return /(spec\.js)/.test(line);
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

编辑:
我无法让上述库工作,所以我自己创建了一个简单的实现。在某些边缘情况下可能会失败,并且可能不是最有效的,但对于我的需求来说已经足够了。

import {RawSourceMap, SourceMapConsumer} from 'source-map-js';

const sourceMaps: {[key: string] : RawSourceMap} = {};
async function getSourceMapFromUri(uri: string) {
  if (sourceMaps[uri] != undefined) {
    return sourceMaps[uri];
  }
  const uriQuery = new URL(uri).search;
  const currentScriptContent = await (await fetch(uri)).text();

  let mapUri = RegExp(/\/\/# sourceMappingURL=(.*)/).exec(currentScriptContent)[1];
  mapUri = new URL(mapUri, uri).href + uriQuery;

  const map = await (await fetch(mapUri)).json();

  sourceMaps[uri] = map;

  return map;
}

async function mapStackTrace(stack: string) {
  const stackLines = stack.split('\n');
  const mappedStack = [];

  for (const line of stackLines) {
    const match = RegExp(/(.*)(http:\/\/.*):(\d+):(\d+)/).exec(line);
    if (match == null) {
      mappedStack.push(line);
      continue;
    }

    const uri = match[2];
    const consumer = new SourceMapConsumer(await getSourceMapFromUri(uri));

    const originalPosition = consumer.originalPositionFor({
      line: parseInt(match[3]),
      column: parseInt(match[4]),
    });

    if (originalPosition.source == null || originalPosition.line == null || originalPosition.column == null) {
      mappedStack.push(line);
      continue;
    }

    mappedStack.push(`${originalPosition.source}:${originalPosition.line}:${originalPosition.column + 1}`);
  }

  return mappedStack.join('\n');
}
Run Code Online (Sandbox Code Playgroud)

(您也可以使用普通库,由于我的特定环境中发生一些错误,source-map我不得不使用)source-map-js