1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | (function() {
|
9 | var ErrorHandler, FCMD, FS, HMSTATUS, M2C, PATH, PKG, SyntaxErrorEx, WRAP, YAML, _defaultLog, assembleError, chalk, extend, printf;
|
10 |
|
11 | HMSTATUS = require('../hmc/dist/core/status-codes');
|
12 |
|
13 | PKG = require('../../package.json');
|
14 |
|
15 | FS = require('fs');
|
16 |
|
17 | FCMD = require('../hmc');
|
18 |
|
19 | PATH = require('path');
|
20 |
|
21 | WRAP = require('word-wrap');
|
22 |
|
23 | M2C = require('../hmc/dist/utils/md2chalk.js');
|
24 |
|
25 | chalk = require('chalk');
|
26 |
|
27 | extend = require('extend');
|
28 |
|
29 | YAML = require('yamljs');
|
30 |
|
31 | printf = require('printf');
|
32 |
|
33 | SyntaxErrorEx = require('../hmc/dist/utils/syntax-error-ex');
|
34 |
|
35 | require('string.prototype.startswith');
|
36 |
|
37 |
|
38 | |
39 |
|
40 |
|
41 |
|
42 |
|
43 | ErrorHandler = module.exports = {
|
44 | init: function(debug, assert, silent) {
|
45 | this.debug = debug;
|
46 | this.assert = assert;
|
47 | this.silent = silent;
|
48 | this.msgs = require('./msg').errors;
|
49 | return this;
|
50 | },
|
51 | err: function(ex, shouldExit) {
|
52 | var o, objError, stack, stackTrace;
|
53 | o = this.silent ? function() {} : _defaultLog;
|
54 | if (ex.pass) {
|
55 | throw ex;
|
56 | }
|
57 | this.msgs = this.msgs || require('./msg').errors;
|
58 | if (ex.fluenterror) {
|
59 | objError = assembleError.call(this, ex);
|
60 | o(this['format_' + objError.etype](objError.msg));
|
61 | if (objError.withStack) {
|
62 | stack = ex.stack || (ex.inner && ex.inner.stack);
|
63 | stack && o(chalk.gray(stack));
|
64 | }
|
65 | if (ex.quit || objError.quit) {
|
66 | if (this.debug) {
|
67 | o(chalk.cyan('Exiting with error code ' + ex.fluenterror.toString()));
|
68 | }
|
69 | if (this.assert) {
|
70 | ex.pass = true;
|
71 | throw ex;
|
72 | }
|
73 | return process.exit(ex.fluenterror);
|
74 | }
|
75 | } else {
|
76 | o(ex);
|
77 | stackTrace = ex.stack || (ex.inner && ex.inner.stack);
|
78 | if (stackTrace && this.debug) {
|
79 | return o(M2C(ex.stack || ex.inner.stack, 'gray'));
|
80 | }
|
81 | }
|
82 | },
|
83 | format_error: function(msg) {
|
84 | msg = msg || '';
|
85 | return chalk.red.bold(msg.toUpperCase().startsWith('ERROR:') ? msg : 'Error: ' + msg);
|
86 | },
|
87 | format_warning: function(brief, msg) {
|
88 | return chalk.yellow(brief) + chalk.yellow(msg || '');
|
89 | },
|
90 | format_custom: function(msg) {
|
91 | return msg;
|
92 | }
|
93 | };
|
94 |
|
95 | _defaultLog = function() {
|
96 | return console.log.apply(console.log, arguments);
|
97 | };
|
98 |
|
99 | assembleError = function(ex) {
|
100 | var etype, msg, quit, se, withStack;
|
101 | msg = '';
|
102 | withStack = false;
|
103 | quit = false;
|
104 | etype = 'warning';
|
105 | if (this.debug) {
|
106 | withStack = true;
|
107 | }
|
108 | switch (ex.fluenterror) {
|
109 | case HMSTATUS.themeNotFound:
|
110 | msg = printf(M2C(this.msgs.themeNotFound.msg, 'yellow'), ex.data);
|
111 | break;
|
112 | case HMSTATUS.copyCSS:
|
113 | msg = M2C(this.msgs.copyCSS.msg, 'red');
|
114 | quit = false;
|
115 | break;
|
116 | case HMSTATUS.resumeNotFound:
|
117 | msg = M2C(this.msgs.resumeNotFound.msg, 'yellow');
|
118 | break;
|
119 | case HMSTATUS.missingCommand:
|
120 | msg = M2C(this.msgs.missingCommand.msg + " (", 'yellow');
|
121 | msg += Object.keys(FCMD.verbs).map(function(v, idx, ar) {
|
122 | return (idx === ar.length - 1 ? chalk.yellow('or ') : '') + chalk.yellow.bold(v.toUpperCase());
|
123 | }).join(chalk.yellow(', ')) + chalk.yellow(").\n\n");
|
124 | msg += chalk.gray(FS.readFileSync(PATH.resolve(__dirname, '../cli/use.txt'), 'utf8'));
|
125 | break;
|
126 | case HMSTATUS.invalidCommand:
|
127 | msg = printf(M2C(this.msgs.invalidCommand.msg, 'yellow'), ex.attempted);
|
128 | break;
|
129 | case HMSTATUS.resumeNotFoundAlt:
|
130 | msg = M2C(this.msgs.resumeNotFoundAlt.msg, 'yellow');
|
131 | break;
|
132 | case HMSTATUS.inputOutputParity:
|
133 | msg = M2C(this.msgs.inputOutputParity.msg);
|
134 | break;
|
135 | case HMSTATUS.createNameMissing:
|
136 | msg = M2C(this.msgs.createNameMissing.msg);
|
137 | break;
|
138 | case HMSTATUS.pdfGeneration:
|
139 | msg = M2C(this.msgs.pdfGeneration.msg, 'bold');
|
140 | if (ex.inner) {
|
141 | msg += chalk.red('\n' + ex.inner);
|
142 | }
|
143 | withStack = true;
|
144 | quit = false;
|
145 | etype = 'error';
|
146 | break;
|
147 | case HMSTATUS.invalid:
|
148 | msg = M2C(this.msgs.invalid.msg, 'red');
|
149 | etype = 'error';
|
150 | break;
|
151 | case HMSTATUS.generateError:
|
152 | msg = (ex.inner && ex.inner.toString()) || ex;
|
153 | quit = false;
|
154 | etype = 'error';
|
155 | break;
|
156 | case HMSTATUS.fileSaveError:
|
157 | msg = printf(M2C(this.msgs.fileSaveError.msg), (ex.inner || ex).toString());
|
158 | etype = 'error';
|
159 | quit = false;
|
160 | break;
|
161 | case HMSTATUS.invalidFormat:
|
162 | ex.data.forEach(function(d) {
|
163 | return msg += printf(M2C(this.msgs.invalidFormat.msg, 'bold'), ex.theme.name.toUpperCase(), d.format.toUpperCase());
|
164 | }, this);
|
165 | break;
|
166 | case HMSTATUS.missingParam:
|
167 | msg = printf(M2C(this.msgs.missingParam.msg), ex.expected, ex.helper);
|
168 | break;
|
169 | case HMSTATUS.invalidHelperUse:
|
170 | msg = printf(M2C(this.msgs.invalidHelperUse.msg), ex.helper);
|
171 | if (ex.error) {
|
172 | msg += '\n--> ' + assembleError.call(this, extend(true, {}, ex, {
|
173 | fluenterror: ex.error
|
174 | })).msg;
|
175 | }
|
176 | quit = false;
|
177 | etype = 'warning';
|
178 | break;
|
179 | case HMSTATUS.notOnPath:
|
180 | msg = printf(M2C(this.msgs.notOnPath.msg, 'bold'), ex.engine);
|
181 | quit = false;
|
182 | etype = 'error';
|
183 | break;
|
184 | case HMSTATUS.readError:
|
185 | if (!ex.quiet) {
|
186 | console.error(printf(M2C(this.msgs.readError.msg, 'red'), ex.file));
|
187 | }
|
188 | msg = ex.inner.toString();
|
189 | etype = 'error';
|
190 | break;
|
191 | case HMSTATUS.mixedMerge:
|
192 | msg = M2C(this.msgs.mixedMerge.msg);
|
193 | quit = false;
|
194 | break;
|
195 | case HMSTATUS.invokeTemplate:
|
196 | msg = M2C(this.msgs.invokeTemplate.msg, 'red');
|
197 | msg += M2C('\n' + WRAP(ex.inner.toString(), {
|
198 | width: 60,
|
199 | indent: ' '
|
200 | }), 'gray');
|
201 | etype = 'custom';
|
202 | break;
|
203 | case HMSTATUS.compileTemplate:
|
204 | etype = 'error';
|
205 | break;
|
206 | case HMSTATUS.themeLoad:
|
207 | msg = M2C(printf(this.msgs.themeLoad.msg, ex.attempted.toUpperCase()), 'red');
|
208 | if (ex.inner && ex.inner.fluenterror) {
|
209 | msg += M2C('\nError: ', 'red') + assembleError.call(this, ex.inner).msg;
|
210 | }
|
211 | quit = true;
|
212 | etype = 'custom';
|
213 | break;
|
214 | case HMSTATUS.parseError:
|
215 | if (SyntaxErrorEx.is(ex.inner)) {
|
216 | console.error(printf(M2C(this.msgs.readError.msg, 'red'), ex.file));
|
217 | se = new SyntaxErrorEx(ex, ex.raw);
|
218 | msg = printf(M2C(this.msgs.parseError.msg, 'red'), se.line, se.col);
|
219 | } else if (ex.inner && ex.inner.line !== void 0 && ex.inner.col !== void 0) {
|
220 | msg = printf(M2C(this.msgs.parseError.msg, 'red'), ex.inner.line, ex.inner.col);
|
221 | } else {
|
222 | msg = ex;
|
223 | }
|
224 | etype = 'error';
|
225 | }
|
226 | return {
|
227 | msg: msg,
|
228 | withStack: withStack,
|
229 | quit: quit,
|
230 | etype: etype
|
231 | };
|
232 | };
|
233 |
|
234 | }).call(this);
|