2013-04-23 18:51:17 +02:00
|
|
|
|
2013-03-28 18:48:37 +01:00
|
|
|
import re
|
2017-09-22 18:30:18 +02:00
|
|
|
import os
|
2013-07-12 22:01:31 +02:00
|
|
|
import sourcemap
|
2016-06-05 04:20:00 +02:00
|
|
|
|
2017-07-28 20:32:57 +02:00
|
|
|
from typing import Dict, List, Text
|
2013-03-28 18:48:37 +01:00
|
|
|
|
|
|
|
|
2017-11-05 11:37:41 +01:00
|
|
|
class SourceMap:
|
2013-07-12 22:01:31 +02:00
|
|
|
'''Map (line, column) pairs from generated to source file.'''
|
2013-03-28 18:48:37 +01:00
|
|
|
|
2017-11-05 11:15:10 +01:00
|
|
|
def __init__(self, sourcemap_dirs: List[Text]) -> None:
|
2017-07-28 20:32:57 +02:00
|
|
|
self._dirs = sourcemap_dirs
|
2017-05-07 17:14:17 +02:00
|
|
|
self._indices = {} # type: Dict[Text, sourcemap.SourceMapDecoder]
|
2013-03-28 18:48:37 +01:00
|
|
|
|
2017-11-05 11:15:10 +01:00
|
|
|
def _index_for(self, minified_src: Text) -> sourcemap.SourceMapDecoder:
|
2013-07-12 22:01:31 +02:00
|
|
|
'''Return the source map index for minified_src, loading it if not
|
|
|
|
already loaded.'''
|
|
|
|
if minified_src not in self._indices:
|
2017-07-28 20:32:57 +02:00
|
|
|
for source_dir in self._dirs:
|
|
|
|
filename = os.path.join(source_dir, minified_src + '.map')
|
|
|
|
if os.path.isfile(filename):
|
|
|
|
with open(filename) as fp:
|
|
|
|
self._indices[minified_src] = sourcemap.load(fp)
|
|
|
|
break
|
2013-03-28 18:48:37 +01:00
|
|
|
|
2013-07-12 22:01:31 +02:00
|
|
|
return self._indices[minified_src]
|
2013-03-28 18:48:37 +01:00
|
|
|
|
2017-11-05 11:15:10 +01:00
|
|
|
def annotate_stacktrace(self, stacktrace: Text) -> Text:
|
2017-05-07 17:14:17 +02:00
|
|
|
out = '' # type: Text
|
2013-03-28 18:48:37 +01:00
|
|
|
for ln in stacktrace.splitlines():
|
|
|
|
out += ln + '\n'
|
2017-07-28 20:32:57 +02:00
|
|
|
match = re.search(r'/static/(?:webpack-bundles|min)/(.+)(\.[\.0-9a-f]+)\.js:(\d+):(\d+)', ln)
|
2013-03-28 18:48:37 +01:00
|
|
|
if match:
|
2013-07-12 22:01:31 +02:00
|
|
|
# Get the appropriate source map for the minified file.
|
|
|
|
minified_src = match.groups()[0] + '.js'
|
|
|
|
index = self._index_for(minified_src)
|
|
|
|
|
2015-11-01 17:14:53 +01:00
|
|
|
gen_line, gen_col = list(map(int, match.groups()[2:4]))
|
2013-07-12 22:01:31 +02:00
|
|
|
# The sourcemap lib is 0-based, so subtract 1 from line and col.
|
|
|
|
try:
|
|
|
|
result = index.lookup(line=gen_line-1, column=gen_col-1)
|
2013-03-28 18:48:37 +01:00
|
|
|
out += (' = %s line %d column %d\n' %
|
2016-12-03 00:04:17 +01:00
|
|
|
(result.src, result.src_line+1, result.src_col+1))
|
2013-07-12 22:01:31 +02:00
|
|
|
except IndexError:
|
2016-11-30 22:49:02 +01:00
|
|
|
out += ' [Unable to look up in source map]\n'
|
2013-03-28 18:48:37 +01:00
|
|
|
|
|
|
|
if ln.startswith(' at'):
|
|
|
|
out += '\n'
|
|
|
|
return out
|