web-dev-qa-db-ja.com

縮小されたjavascriptスタックトレースを取得し、ソースマップに対して実行して、適切なエラーを取得するにはどうすればよいですか?

私たちの本番サーバーでは、公開されたjavascriptを縮小しましたが、エラーに基づいて何が起こっているのかをユーザーに理解させたくないため、マップファイルを含めていません。

angular例外($ exceptionHandlerによってキャッチされた)を電子メールで自分自身に転送するために作成したログサービスがあります。ただし、このスタックトレースはほとんど読み取れません。

n is not defined
    at o (http://localhost:9000/build/app.min.js:1:3284)
    at new NameController (http://localhost:9000/build/app.min.js:1:3412)
    at e (http://localhost:9000/build/bower.min.js:44:193)
    at Object.g.instantiate (http://localhost:9000/build/bower.min.js:44:310)
    at b.$get (http://localhost:9000/build/bower.min.js:85:313)
    at d.compile (http://localhost:9000/build/bower.min.js:321:23333)
    at aa (http://localhost:9000/build/bower.min.js:78:90)
    at K (http://localhost:9000/build/bower.min.js:67:39)
    at g (http://localhost:9000/build/bower.min.js:59:410)
    at http://localhost:9000/build/bower.min.js:58:480 <ui-view class="ng-scope">

私が疑問に思っているのは、マップファイルを介して(または別の方法がある場合はマップファイルを介してではなく)実際の縮小されていないソースコードに対してこのスタックトレースを分析できるプログラムはありますか?

29
Alex Kibler

あなたがしたいのは、ソースマップを解析することです。これはWebブラウザとは何の関係もありません。あなたがする必要があるのは、縮小された参照を縮小されていないリソースに変換することです。

NodeJSの使用経験がある場合は、これを行うパッケージがすでに存在します。

https://github.com/mozilla/source-map/

ライブラリをインストールするには

npm install -g source-map

「issue.js」という名前のファイルを作成します

fs = require('fs');
var sourceMap = require('source-map');
var smc = new sourceMap.sourceMapConsumer(fs.readFileSync("./app.min.js.map","utf8"));
console.log(smc.originalPositionFor({line: 1, column: 3284}));

ノードでファイルを実行する

node issue.js

スタックトレースの最初の行の元のファイルの場所をコンソールに出力する必要があります。

注:使いやすさのためにソースマップをグローバルにインストールすることをお伝えしますが、必要なことを実行してローカルにインストールするノードプロジェクトを作成することもできます。

15
Reactgular

外部からソースマップファイルにアクセスでき、同じファイル構造を取得できれば、うまくいくと思いますが、ブラウザ以外でそれを支援するツールはありません。

実行中のブラウザにデータがあるという追加の利点により、ソースマップでも取得できないローカルをチェックできます。

エラー報告を行うには、 rollbar などのツールを検討することをお勧めします。これにより、デバッグに役立つように、各フレームのすべてのローカルが報告されます。セキュリティ上の懸念に対処するために、 ブラウザ外のソースマップ をサポートしています。

1
Euan

@ Reactgular's の回答に追加すると、以下のスニペットは最新バージョンのソースマップで機能します

_  const rawSourceMap = fs.readFileSync("./app.min.js.map","utf8");

  const whatever = sourceMap.SourceMapConsumer.with(rawSourceMap, null, consumer => {
    console.log(consumer.originalPositionFor({
      line: 1,
      column: 3284
    }));
  });
_

そして、スレッドの議論に/\/(\w*[-\.]?\w*).js:\d*:\d*/gのような単純な正規表現を追加します

以下は、スタックトレース内のすべての行番号を見つけるための非常に単純な正規表現です。

_  //regex for patterns like utils.js, utils123.js, utils-name.js, utils.version.js
  var patt = /\/(\w*[-\.]?\w*).js:\d*:\d*/g; 
  // returns matches like ['/app.min.js:1:3284', '/bower.min.js:44:193', ..]
  var errorPositions = line.match(patt);
  console.log(errorPositions);
  if(!errorPositions || errorPositions.length === 0) {
      console.log("No error line numbers detected in the file. Ensure your stack trace file is proper");
      return;
  }
  errorPositions.forEach(function(error) {
    findInSourceMap(error);
  });
});
_
0
Manoj