1 | var ansi = require('ansi-escape-sequences')
|
2 | var strip = require('strip-ansi')
|
3 | var path = require('path')
|
4 | var fs = require('fs')
|
5 |
|
6 | var cwd = process.cwd()
|
7 |
|
8 | module.exports = ttyError
|
9 |
|
10 | function ttyError (src, sub, err) {
|
11 | if (!err.filename || !err.loc) return err
|
12 |
|
13 | var longFilename = err.filename
|
14 | var filename = path.relative(cwd, longFilename)
|
15 | var loc = err.loc
|
16 | var line = loc.line
|
17 | var col = loc.column + 1
|
18 |
|
19 | var lineNum = String(line) + ' '
|
20 | var padLen = lineNum.length
|
21 | var empty = padLeft('|', padLen + 1)
|
22 | var arrow = padLeft('--> ', padLen + 4 - 1)
|
23 | var syntaxError = padLeft('', col) + '^ Syntax Error'
|
24 |
|
25 | try {
|
26 | var file = fs.readFileSync(longFilename, 'utf8')
|
27 | } catch (e) {
|
28 | return err
|
29 | }
|
30 |
|
31 | var arr = file.split('\n')
|
32 | var code = arr[line - 1] || '<code>'
|
33 |
|
34 | var str = ''
|
35 | str += `${clr(`Failed while processing '${src}'.`, 'red')}\n\n`
|
36 | str += clr(arrow, 'blue') + clr(filename + `:${line}:${col}`, 'white') + '\n'
|
37 | str += clr(empty, 'blue') + '\n'
|
38 | str += clr(lineNum + '|', 'blue') + ` ${clr(code, 'white')}\n`
|
39 | str += clr(empty, 'blue') + clr(syntaxError, 'red') + '\n\n'
|
40 | str += clr(`Hmmm. We're having trouble parsing a file.`, 'white')
|
41 |
|
42 | err.pretty = str
|
43 | return err
|
44 | }
|
45 |
|
46 | function clr (text, color, style) {
|
47 | return process.stdout.isTTY ? ansi.format(text, color, style) : text
|
48 | }
|
49 |
|
50 | function padLeft (str, num, char) {
|
51 | str = String(str)
|
52 | var len = strip(str).length
|
53 | return pad(num - len, char) + str
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | function pad (len, char) {
|
63 | char = String(char === undefined ? ' ' : char)
|
64 | var res = ''
|
65 | while (res.length < len) res += char
|
66 | return res
|
67 | }
|