nodexh 1.1.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,4 +56,9 @@ Use `nodexh path/to/file.js` instead of `node path/to/file.js`, and you're good
56
56
  * [ ] fix async stacktraces (probably not yet handled correctly; might be issue with `stackman`?)
57
57
  * [ ] consider [utf8ize-sourcemaps](https://github.com/twada/utf8ize-sourcemaps) in case there should be
58
58
  problems w/ 32bit characters
59
+ * [ ] truncate long lines in context
60
+ * [ ] offer capabilities of NodeXH as API so applications (such as test libraries) can easily retrieve
61
+ source code, display source lines with contexts
62
+
63
+
59
64
 
package/bin/nodexh CHANGED
@@ -1,3 +1,29 @@
1
1
  #!/usr/bin/env bash
2
- node --require "$(realpath "$0")"/../../lib/main.js --trace-warnings --enable-source-maps --stack-trace-limit=100 "$@"
2
+
3
+ realpath() {
4
+ # thx to https://github.com/whatwg/html-build/issues/90
5
+ OURPWD=$PWD
6
+ cd "$(dirname "$1")"
7
+ LINK=$(readlink "$(basename "$1")")
8
+ while [ "$LINK" ]; do
9
+ cd "$(dirname "$LINK")"
10
+ LINK=$(readlink "$(basename "$1")")
11
+ done
12
+ REALPATH="$PWD/$(basename "$1")"
13
+ cd "$OURPWD"
14
+ echo "$REALPATH"
15
+ }
16
+
17
+ node \
18
+ --require "$(realpath "$0")"/../../lib/main.js \
19
+ --trace-warnings \
20
+ --enable-source-maps \
21
+ --stack-trace-limit=100 \
22
+ --expose-gc \
23
+ "$@"
24
+ # --nouse_idle_notification \
25
+ # --trace_gc \
26
+
27
+
28
+
3
29
 
package/lib/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function() {
2
2
  'use strict';
3
- var CND, FS, PATH, alert, badge, bold, cyan, debug, echo, exit_handler, fetch_mapped_location, get_context, get_error_callsites, gold, green, grey, help, info, load_source_map, log, red, reverse, rpr, show_error_with_source_context, steel, underline, urge, warn, whisper, white, write_to_stderr, yellow;
3
+ var CND, FS, PATH, _get_context, alert, badge, bold, cyan, debug, echo, exit_handler, fetch_mapped_location, get_context, get_error_callsites, get_stacktracey, gold, green, grey, help, info, load_source_map, log, red, reverse, rpr, show_error_with_source_context, show_stacktracey, steel, underline, urge, warn, whisper, white, write_to_stderr, yellow;
4
4
 
5
5
  //###########################################################################################################
6
6
  CND = require('cnd');
@@ -57,7 +57,8 @@
57
57
  });
58
58
  } catch (error1) {
59
59
  error = error1;
60
- warn('^7763-3^', "!!!!!!!!!!!!!!!!!", error.message);
60
+ // warn '^7763-3^', "!!!!!!!!!!!!!!!!!", { path, }
61
+ // warn '^7763-3^', "!!!!!!!!!!!!!!!!!", error.message
61
62
  return {path, linenr, colnr};
62
63
  }
63
64
  //.........................................................................................................
@@ -75,57 +76,62 @@
75
76
 
76
77
  //-----------------------------------------------------------------------------------------------------------
77
78
  get_context = function(path, linenr, colnr, width) {
78
- var R, c0, c1, coldelta, delta, effect, error, first_idx, hilite, i, idx, last_idx, len, line, lines, ref, this_linenr, this_linenr_txt, width2;
79
+ var error;
79
80
  try {
80
- //.........................................................................................................
81
- lines = (FS.readFileSync(path, {
82
- encoding: 'utf-8'
83
- })).split('\n');
84
- delta = 1;
85
- coldelta = 5;
86
- /* TAINT use more meaningful limit like n times the terminal width, assuming default of 100 */
87
- // effect = underline
88
- // effect = bold
89
- effect = reverse;
90
- first_idx = Math.max(0, linenr - 1 - delta);
91
- last_idx = Math.min(lines.length - 1, linenr - 1 + delta);
92
- R = [];
93
- ref = lines.slice(first_idx, +last_idx + 1 || 9e9);
94
- for (idx = i = 0, len = ref.length; i < len; idx = ++i) {
95
- line = ref[idx];
96
- this_linenr = first_idx + idx + 1;
97
- this_linenr_txt = (this_linenr.toString().padStart(4)) + '│ ';
98
- if (this_linenr === linenr) {
99
- c0 = colnr - 1;
100
- c1 = colnr + coldelta;
101
- hilite = effect(line.slice(c0, c1));
102
- line = line.slice(0, c0) + hilite + line.slice(c1);
103
- if (c1 > width) {
104
- width2 = Math.floor(width / 2);
105
- line = '... ' + line.slice(c1 - width2, +(c1 + hilite.length - (c1 - c0) + width2) + 1 || 9e9) + ' ...';
106
- } else {
107
- line = line.slice(0, +width + 1 || 9e9);
108
- }
109
- R.push(`${grey(this_linenr_txt)}${cyan(line)}`);
110
- } else {
111
- R.push(`${grey(this_linenr_txt)}${grey(line)}`);
112
- }
113
- }
81
+ return _get_context(path, linenr, colnr, width);
114
82
  } catch (error1) {
115
- // R = R.join '\n'
116
83
  error = error1;
117
84
  if (error.code !== 'ENOENT') {
118
85
  throw error;
119
86
  }
120
- return [];
121
87
  }
122
- // return [ ( red "!!! #{rpr error.message} !!!" ), ]
88
+ return [];
89
+ };
90
+
91
+ //-----------------------------------------------------------------------------------------------------------
92
+ // return [ ( red "!!! #{rpr error.message} !!!" ), ]
93
+ _get_context = function(path, linenr, colnr, width) {
94
+ /* TAINT perform line length adjustment, hiliting in dedicated method */
95
+ var R, c0, c1, coldelta, delta, effect, first_idx, hilite, i, idx, last_idx, len, line, lines, ref, this_linenr, this_linenr_txt, width2;
96
+ lines = (FS.readFileSync(path, {
97
+ encoding: 'utf-8'
98
+ })).split('\n');
99
+ delta = 1;
100
+ coldelta = 5;
101
+ effect = reverse;
102
+ first_idx = Math.max(0, linenr - 1 - delta);
103
+ last_idx = Math.min(lines.length - 1, linenr - 1 + delta);
104
+ R = [];
105
+ ref = lines.slice(first_idx, +last_idx + 1 || 9e9);
106
+ for (idx = i = 0, len = ref.length; i < len; idx = ++i) {
107
+ line = ref[idx];
108
+ this_linenr = first_idx + idx + 1;
109
+ this_linenr_txt = (this_linenr.toString().padStart(4)) + '│ ';
110
+ if (this_linenr !== linenr) {
111
+ /* TAINT should adjust overlong context lines as well */
112
+ R.push(`${grey(this_linenr_txt)}${grey(line)}`);
113
+ continue;
114
+ }
115
+ c0 = colnr - 1;
116
+ c1 = colnr + coldelta;
117
+ hilite = effect(line.slice(c0, c1));
118
+ line = line.slice(0, c0) + hilite + line.slice(c1);
119
+ if (c1 > width) {
120
+ width2 = Math.floor(width / 2);
121
+ line = '... ' + line.slice(c1 - width2, +(c1 + hilite.length - (c1 - c0) + width2) + 1 || 9e9) + ' ...';
122
+ } else {
123
+ line = line.slice(0, +width + 1 || 9e9);
124
+ }
125
+ R.push(`${grey(this_linenr_txt)}${cyan(line)}`);
126
+ }
127
+ // R = R.join '\n'
123
128
  return R;
124
129
  };
125
130
 
126
131
  //-----------------------------------------------------------------------------------------------------------
127
132
  show_error_with_source_context = async function(error, headline) {
128
- var arrowhead, arrowshaft, callsite, callsites, colnr, context_line, i, j, len, len1, linenr, path, ref, relpath, width;
133
+ /* TAINT use proper methods to format with multiple colors */
134
+ var arrowhead, arrowshaft, callsite, callsites, colnr, context_line, fname, fname_txt, i, j, len, len1, linenr, path, ref, ref1, ref2, relpath, width, width1;
129
135
  /* From https://github.com/watson/stackman#gotchas: "This module works because V8 (the JavaScript engine
130
136
  behind Node.js) allows us to hook into the stack trace generator function before that stack trace is
131
137
  generated. It's triggered by accessing the .stack property on the Error object, so please don't do
@@ -137,7 +143,7 @@
137
143
  callsites = get_error_callsites(error);
138
144
  //.........................................................................................................
139
145
  if ((callsites == null) || (callsites.length === 0)) {
140
- write_to_stderr(CND.red(CND.reverse("error has no associated callsites:")));
146
+ write_to_stderr(CND.red(CND.reverse("^455756^ error has no associated callsites:")));
141
147
  write_to_stderr(CND.red(CND.reverse(rpr(error))));
142
148
  return null;
143
149
  }
@@ -156,48 +162,135 @@
156
162
  linenr = callsite.getLineNumber();
157
163
  colnr = callsite.getColumnNumber();
158
164
  //.......................................................................................................
159
- if (path.startsWith('internal/')) {
160
- write_to_stderr(arrowhead, grey(`${path} #${linenr}`));
165
+ if ((path.startsWith('node:internal/')) || (path.startsWith('internal/'))) {
166
+ write_to_stderr(arrowhead, grey(`${path} @ ${linenr},${colnr}`));
161
167
  continue;
162
168
  }
163
169
  //.......................................................................................................
164
- // debug '^344463^', { relpath, linenr, colnr, }
165
170
  // write_to_stderr()
166
171
  // write_to_stderr steel bold reverse ( "#{relpath} ##{linenr}:" ).padEnd 108
172
+ fname = (ref = (ref1 = callsite.getFunctionName()) != null ? ref1 : callsite.getMethodName()) != null ? ref : null;
167
173
  ({path, linenr, colnr} = (await fetch_mapped_location(path, linenr, colnr)));
168
174
  relpath = PATH.relative(process.cwd(), path);
169
- write_to_stderr(arrowhead, gold(`${relpath} @ ${linenr},${colnr}: \x1b[38;05;234m`.padEnd(width, '—')));
170
- ref = (await get_context(path, linenr, colnr, width));
171
- for (j = 0, len1 = ref.length; j < len1; j++) {
172
- context_line = ref[j];
175
+ if (fname != null) {
176
+ fname_txt = steel(fname);
177
+ width1 = width + (fname_txt.length - fname.length);
178
+ write_to_stderr(arrowhead, gold(`${relpath} @ ${linenr},${colnr}: ${fname_txt}() \x1b[38;05;234m`.padEnd(width1, '—')));
179
+ } else {
180
+ write_to_stderr(arrowhead, gold(`${relpath} @ ${linenr},${colnr}: \x1b[38;05;234m`.padEnd(width, '—')));
181
+ }
182
+ ref2 = (await get_context(path, linenr, colnr, width));
183
+ for (j = 0, len1 = ref2.length; j < len1; j++) {
184
+ context_line = ref2[j];
173
185
  write_to_stderr(arrowshaft, context_line);
174
186
  }
175
187
  }
176
188
  alert('^77765-2^', reverse(bold(headline)));
177
- // if error?.message?
189
+ // urge "^94843^ error.stack:", rpr error.stack
190
+ // urge "^94843^ error.message:", rpr error.message
191
+ // urge "^94843^ error.code:", rpr error.code
192
+ // urge "^94843^ error.name:", rpr error.name
193
+ // urge "^94843^ error.type:", rpr error.type
194
+ // urge "^94843^ error.toString():", rpr error.toString()
195
+ // urge "^94843^ error:", rpr error
196
+ // CATALOGUING = require '../../multimix/lib/cataloguing'
197
+ // urge "^94843^", ( CATALOGUING.all_keys_of error )
178
198
  return null;
179
199
  };
180
200
 
181
201
  //-----------------------------------------------------------------------------------------------------------
182
- exit_handler = async function(error) {
183
- var message, ref;
184
- message = ' EXCEPTION: ' + ((ref = error != null ? error.message : void 0) != null ? ref : "an unrecoverable condition occurred");
202
+ exit_handler = async function(error, origin) {
203
+ var message, ref, ref1, ref2, type;
204
+ /* TAINT origin never used */
205
+ // show_stacktracey error
206
+ // debug '^4488^', error
207
+ // debug '^4488^', await origin
208
+ // return null
209
+ type = (ref = (ref1 = error.code) != null ? ref1 : error.name) != null ? ref : 'EXCEPTION';
210
+ message = ` ${type}: ` + ((ref2 = error != null ? error.message : void 0) != null ? ref2 : "an unrecoverable condition occurred");
185
211
  await show_error_with_source_context(error, message);
186
212
  setImmediate((function() {
187
213
  return process.exit(111);
188
214
  }));
189
- // process.exit 111
190
215
  return null;
191
216
  };
192
217
 
218
+ //###########################################################################################################
219
+ //###########################################################################################################
220
+ //###########################################################################################################
221
+ get_stacktracey = function(error) {
222
+ var R, StackTracey, d, i, idx, ref, s, stack;
223
+ StackTracey = require('stacktracey');
224
+ stack = (new StackTracey(error)).withSources();
225
+ // stack = stack.clean()
226
+ R = [];
227
+ for (idx = i = ref = stack.items.length - 1; i >= 0; idx = i += -1) {
228
+ d = stack.items[idx];
229
+ // debug '^2798^', ( k for k of d )
230
+ s = {
231
+ // target_path: d.file
232
+ relpath: d.fileRelative, // fileShort
233
+ native: d.native,
234
+ // is_nodejs: d.native
235
+ is_other: d.thirdParty,
236
+ line: d.line,
237
+ column: d.column,
238
+ source: d.sourceLine,
239
+ error: d.error
240
+ };
241
+ // for k in [ 'sourceLine', 'native', 'file', 'line', 'column', 'calleeShort', 'fileRelative', 'fileShort', 'fileName', 'thirdParty', 'name',]
242
+ // debug k, rpr d[ k ]
243
+ R.push(s);
244
+ }
245
+ // info '\n' + stack.asTable()
246
+ return R;
247
+ };
248
+
249
+ show_stacktracey = function(error) {
250
+ var d, i, len, ref, ref1;
251
+ ref = get_stacktracey(error);
252
+ for (i = 0, len = ref.length; i < len; i++) {
253
+ d = ref[i];
254
+ echo(CND.steel('^44872^ ' + `${d.relpath} @ ${d.line}:${d.column}`));
255
+ /* NOTE errors:
256
+ ENOENT: no such file or directory
257
+ EISDIR: illegal operation on a directory, read
258
+ 'Cannot read property 'originalPositionFor' of undefined'
259
+ */
260
+ if (d.error != null) {
261
+ echo(CND.red('^44873^ ' + ((ref1 = d.error.message) != null ? ref1 : "an error occurred")));
262
+ } else {
263
+ echo(CND.yellow('^44874^ ' + `${rpr(d.source.slice(0, 101))}`));
264
+ }
265
+ }
266
+ return null;
267
+ };
268
+
269
+ //###########################################################################################################
270
+ //###########################################################################################################
271
+ //###########################################################################################################
272
+
193
273
  //###########################################################################################################
194
274
  if (global[Symbol.for('cnd-exception-handler')] == null) {
275
+ null;
195
276
  global[Symbol.for('cnd-exception-handler')] = true;
196
- process.on('uncaughtException', exit_handler);
197
- process.on('unhandledRejection', exit_handler);
277
+ process.once('uncaughtException', exit_handler);
278
+ process.once('unhandledRejection', exit_handler);
198
279
  }
199
280
 
200
- /*
281
+ // do =>
282
+ // process.stderr.on 'data', ( data ) => debug "^6863-1^ (stderr.on 'data'):", rpr data
283
+ // process.stdout.on 'data', ( data ) => debug "^6863-2^ (stdout.on 'data'):", rpr data
284
+ // process.stderr.on 'end', => debug "^6863-1^ (stderr.on 'end')"
285
+ // process.stdout.on 'end', => debug "^6863-2^ (stdout.on 'end')"
286
+ // debug '^6456^'
287
+ // echo "^4564^ echo to stdout"
288
+ // warn "^4564^ warn to stderr"
289
+ // process.stderr.write "this goes to stderr\n"
290
+ // process.stdout.write "this goes to stdout\n"
291
+ // process.on 'message', ( message ) -> debug "^6863-3^' (process.on 'message'):", rpr message
292
+ // process.on 'warning', ( warning ) -> debug "^6863-3^' (process.on 'warning'):", rpr warning
293
+ /*
201
294
  callsite.getThis() - returns the value of this
202
295
  callsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.
203
296
  callsite.getFunction() - returns the current function
package/lib/main.js.map CHANGED
@@ -6,8 +6,8 @@
6
6
  "../src/main.coffee"
7
7
  ],
8
8
  "names": [],
9
- "mappings": "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",
9
+ "mappings": "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",
10
10
  "sourcesContent": [
11
- "\n\n'use strict'\n\n\n############################################################################################################\nCND = require 'cnd'\nrpr = CND.rpr\nbadge = 'nodexh'\nlog = CND.get_logger 'plain', badge\ndebug = CND.get_logger 'debug', badge\ninfo = CND.get_logger 'info', badge\nwarn = CND.get_logger 'warn', badge\nalert = CND.get_logger 'alert', badge\nhelp = CND.get_logger 'help', badge\nurge = CND.get_logger 'urge', badge\nwhisper = CND.get_logger 'whisper', badge\necho = CND.echo.bind CND\n# stackman = ( require 'stackman' )()\nget_error_callsites = require 'error-callsites'\nload_source_map = ( require 'util' ).promisify ( require 'load-source-map' )\nFS = require 'fs'\nPATH = require 'path'\n{ red\n green\n steel\n grey\n cyan\n bold\n gold\n white\n yellow\n reverse\n underline\n bold } = CND\n# types = new ( require '../../intertype' ).Intertype()\n# { isa } = types.export()\n\n#-----------------------------------------------------------------------------------------------------------\nwrite_to_stderr = ( P... ) -> process.stderr.write ' ' + CND.pen P...\n\n#-----------------------------------------------------------------------------------------------------------\nfetch_mapped_location = ( path, linenr, colnr ) ->\n try\n sourcemap = await load_source_map path\n smp = sourcemap.originalPositionFor { line: linenr, column: colnr, }\n catch error\n warn '^7763-3^', \"!!!!!!!!!!!!!!!!!\", error.message\n return { path, linenr, colnr, }\n #.........................................................................................................\n if ( smp? ) and ( smp.source? ) and ( smp.source isnt '' ) and ( smp.line? ) and ( smp.column? )\n mapped_path = PATH.join ( PATH.dirname path ), smp.source\n return { path: mapped_path, linenr: smp.line, colnr: smp.column, }\n #.........................................................................................................\n return { path, linenr, colnr, }\n\n#-----------------------------------------------------------------------------------------------------------\nget_context = ( path, linenr, colnr, width ) ->\n #.........................................................................................................\n try\n lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\\n'\n delta = 1\n coldelta = 5\n ### TAINT use more meaningful limit like n times the terminal width, assuming default of 100 ###\n # effect = underline\n # effect = bold\n effect = reverse\n first_idx = Math.max 0, linenr - 1 - delta\n last_idx = Math.min lines.length - 1, linenr - 1 + delta\n R = []\n for line, idx in lines[ first_idx .. last_idx ]\n this_linenr = first_idx + idx + 1\n this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '\n if this_linenr is linenr\n c0 = colnr - 1\n c1 = colnr + coldelta\n hilite = effect line[ c0 ... c1 ]\n line = line[ ... c0 ] + hilite + line[ c1 .. ]\n if c1 > width\n width2 = Math.floor width / 2\n line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'\n else\n line = line[ .. width ]\n R.push \"#{grey this_linenr_txt}#{cyan line}\"\n else\n R.push \"#{grey this_linenr_txt}#{grey line}\"\n # R = R.join '\\n'\n catch error\n throw error unless error.code is 'ENOENT'\n # return [ ( red \"!!! #{rpr error.message} !!!\" ), ]\n return []\n return R\n\n#-----------------------------------------------------------------------------------------------------------\nshow_error_with_source_context = ( error, headline ) ->\n ### From https://github.com/watson/stackman#gotchas: \"This module works because V8 (the JavaScript engine\n behind Node.js) allows us to hook into the stack trace generator function before that stack trace is\n generated. It's triggered by accessing the .stack property on the Error object, so please don't do\n that before parsing the error to stackman, else this will not work!\" ###\n alert '^77765-1^', reverse bold headline\n arrowhead = white '▲'\n arrowshaft = white '│'\n width = process.stdout.columns\n callsites = get_error_callsites error\n #.........................................................................................................\n if ( not callsites? ) or ( callsites.length is 0 )\n write_to_stderr CND.red CND.reverse \"error has no associated callsites:\"\n write_to_stderr CND.red CND.reverse rpr error\n return null\n #.........................................................................................................\n callsites.reverse()\n #.........................................................................................................\n for callsite in callsites\n path = callsite.getFileName()\n #.......................................................................................................\n unless path?\n write_to_stderr grey '—'.repeat 108\n continue\n #.......................................................................................................\n linenr = callsite.getLineNumber()\n colnr = callsite.getColumnNumber()\n #.......................................................................................................\n if path.startsWith 'internal/'\n write_to_stderr arrowhead, grey \"#{path} ##{linenr}\"\n continue\n #.......................................................................................................\n # debug '^344463^', { relpath, linenr, colnr, }\n # write_to_stderr()\n # write_to_stderr steel bold reverse ( \"#{relpath} ##{linenr}:\" ).padEnd 108\n { path\n linenr\n colnr } = await fetch_mapped_location path, linenr, colnr\n relpath = PATH.relative process.cwd(), path\n write_to_stderr arrowhead, gold ( \"#{relpath} @ #{linenr},#{colnr}: \\x1b[38;05;234m\".padEnd width, '—' )\n for context_line in await get_context path, linenr, colnr, width\n write_to_stderr arrowshaft, context_line\n alert '^77765-2^', reverse bold headline\n # if error?.message?\n return null\n\n#-----------------------------------------------------------------------------------------------------------\nexit_handler = ( error ) ->\n message = ' EXCEPTION: ' + ( error?.message ? \"an unrecoverable condition occurred\" )\n await show_error_with_source_context error, message\n setImmediate ( -> process.exit 111 )\n # process.exit 111\n return null\n\n\n\n############################################################################################################\nunless global[ Symbol.for 'cnd-exception-handler' ]?\n global[ Symbol.for 'cnd-exception-handler' ] = true\n process.on 'uncaughtException', exit_handler\n process.on 'unhandledRejection', exit_handler\n\n###\ncallsite.getThis() - returns the value of this\ncallsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.\ncallsite.getFunction() - returns the current function\ncallsite.getFunctionName() - returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.\ncallsite.getMethodName() - returns the name of the property of this or one of its prototypes that holds the current function\ncallsite.getFileName() - if this function was defined in a script returns the name of the script\ncallsite.getLineNumber() - if this function was defined in a script returns the current line number\ncallsite.getColumnNumber() - if this function was defined in a script returns the current column number\ncallsite.getEvalOrigin() - if this function was created using a call to eval returns a CallSite object representing the location where eval was called\ncallsite.isToplevel() - is this a toplevel invocation, that is, is this the global object?\ncallsite.isEval() - does this call take place in code defined by a call to eval?\ncallsite.isNative() - is this call in native V8 code?\ncallsite.isConstructor() - is this a constructor c\n###\n\n"
11
+ "\n\n'use strict'\n\n\n############################################################################################################\nCND = require 'cnd'\nrpr = CND.rpr\nbadge = 'nodexh'\nlog = CND.get_logger 'plain', badge\ndebug = CND.get_logger 'debug', badge\ninfo = CND.get_logger 'info', badge\nwarn = CND.get_logger 'warn', badge\nalert = CND.get_logger 'alert', badge\nhelp = CND.get_logger 'help', badge\nurge = CND.get_logger 'urge', badge\nwhisper = CND.get_logger 'whisper', badge\necho = CND.echo.bind CND\n# stackman = ( require 'stackman' )()\nget_error_callsites = require 'error-callsites'\nload_source_map = ( require 'util' ).promisify ( require 'load-source-map' )\nFS = require 'fs'\nPATH = require 'path'\n{ red\n green\n steel\n grey\n cyan\n bold\n gold\n white\n yellow\n reverse\n underline\n bold } = CND\n# types = new ( require '../../intertype' ).Intertype()\n# { isa } = types.export()\n\n#-----------------------------------------------------------------------------------------------------------\nwrite_to_stderr = ( P... ) -> process.stderr.write ' ' + CND.pen P...\n\n#-----------------------------------------------------------------------------------------------------------\nfetch_mapped_location = ( path, linenr, colnr ) ->\n try\n sourcemap = await load_source_map path\n smp = sourcemap.originalPositionFor { line: linenr, column: colnr, }\n catch error\n # warn '^7763-3^', \"!!!!!!!!!!!!!!!!!\", { path, }\n # warn '^7763-3^', \"!!!!!!!!!!!!!!!!!\", error.message\n return { path, linenr, colnr, }\n #.........................................................................................................\n if ( smp? ) and ( smp.source? ) and ( smp.source isnt '' ) and ( smp.line? ) and ( smp.column? )\n mapped_path = PATH.join ( PATH.dirname path ), smp.source\n return { path: mapped_path, linenr: smp.line, colnr: smp.column, }\n #.........................................................................................................\n return { path, linenr, colnr, }\n\n#-----------------------------------------------------------------------------------------------------------\nget_context = ( path, linenr, colnr, width ) ->\n try return ( _get_context path, linenr, colnr, width ) catch error\n throw error unless error.code is 'ENOENT'\n # return [ ( red \"!!! #{rpr error.message} !!!\" ), ]\n return []\n\n#-----------------------------------------------------------------------------------------------------------\n_get_context = ( path, linenr, colnr, width ) ->\n lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\\n'\n delta = 1\n coldelta = 5\n effect = reverse\n first_idx = Math.max 0, linenr - 1 - delta\n last_idx = Math.min lines.length - 1, linenr - 1 + delta\n R = []\n for line, idx in lines[ first_idx .. last_idx ]\n this_linenr = first_idx + idx + 1\n this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '\n if this_linenr isnt linenr\n ### TAINT should adjust overlong context lines as well ###\n R.push \"#{grey this_linenr_txt}#{grey line}\"\n continue\n ### TAINT perform line length adjustment, hiliting in dedicated method ###\n c0 = colnr - 1\n c1 = colnr + coldelta\n hilite = effect line[ c0 ... c1 ]\n line = line[ ... c0 ] + hilite + line[ c1 .. ]\n if c1 > width\n width2 = Math.floor width / 2\n line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'\n else\n line = line[ .. width ]\n R.push \"#{grey this_linenr_txt}#{cyan line}\"\n # R = R.join '\\n'\n return R\n\n#-----------------------------------------------------------------------------------------------------------\nshow_error_with_source_context = ( error, headline ) ->\n ### From https://github.com/watson/stackman#gotchas: \"This module works because V8 (the JavaScript engine\n behind Node.js) allows us to hook into the stack trace generator function before that stack trace is\n generated. It's triggered by accessing the .stack property on the Error object, so please don't do\n that before parsing the error to stackman, else this will not work!\" ###\n alert '^77765-1^', reverse bold headline\n arrowhead = white '▲'\n arrowshaft = white '│'\n width = process.stdout.columns\n callsites = get_error_callsites error\n #.........................................................................................................\n if ( not callsites? ) or ( callsites.length is 0 )\n write_to_stderr CND.red CND.reverse \"^455756^ error has no associated callsites:\"\n write_to_stderr CND.red CND.reverse rpr error\n return null\n #.........................................................................................................\n callsites.reverse()\n #.........................................................................................................\n for callsite in callsites\n path = callsite.getFileName()\n #.......................................................................................................\n unless path?\n write_to_stderr grey '—'.repeat 108\n continue\n #.......................................................................................................\n linenr = callsite.getLineNumber()\n colnr = callsite.getColumnNumber()\n #.......................................................................................................\n if ( path.startsWith 'node:internal/' ) or ( path.startsWith 'internal/' )\n write_to_stderr arrowhead, grey \"#{path} @ #{linenr},#{colnr}\"\n continue\n #.......................................................................................................\n # write_to_stderr()\n # write_to_stderr steel bold reverse ( \"#{relpath} ##{linenr}:\" ).padEnd 108\n fname = callsite.getFunctionName() ? callsite.getMethodName() ? null\n { path\n linenr\n colnr } = await fetch_mapped_location path, linenr, colnr\n relpath = PATH.relative process.cwd(), path\n if fname?\n ### TAINT use proper methods to format with multiple colors ###\n fname_txt = steel fname\n width1 = width + ( fname_txt.length - fname.length )\n write_to_stderr arrowhead, gold ( \"#{relpath} @ #{linenr},#{colnr}: #{fname_txt}() \\x1b[38;05;234m\".padEnd width1, '—' )\n else\n write_to_stderr arrowhead, gold ( \"#{relpath} @ #{linenr},#{colnr}: \\x1b[38;05;234m\".padEnd width, '—' )\n for context_line in await get_context path, linenr, colnr, width\n write_to_stderr arrowshaft, context_line\n alert '^77765-2^', reverse bold headline\n # urge \"^94843^ error.stack:\", rpr error.stack\n # urge \"^94843^ error.message:\", rpr error.message\n # urge \"^94843^ error.code:\", rpr error.code\n # urge \"^94843^ error.name:\", rpr error.name\n # urge \"^94843^ error.type:\", rpr error.type\n # urge \"^94843^ error.toString():\", rpr error.toString()\n # urge \"^94843^ error:\", rpr error\n # CATALOGUING = require '../../multimix/lib/cataloguing'\n # urge \"^94843^\", ( CATALOGUING.all_keys_of error )\n return null\n\n#-----------------------------------------------------------------------------------------------------------\nexit_handler = ( error, origin ) ->\n ### TAINT origin never used ###\n # show_stacktracey error\n # debug '^4488^', error\n # debug '^4488^', await origin\n # return null\n type = error.code ? error.name ? 'EXCEPTION'\n message = \" #{type}: \" + ( error?.message ? \"an unrecoverable condition occurred\" )\n await show_error_with_source_context error, message\n setImmediate ( -> process.exit 111 )\n return null\n\n############################################################################################################\n############################################################################################################\n############################################################################################################\n\nget_stacktracey = ( error ) ->\n StackTracey = require 'stacktracey'\n stack = ( new StackTracey error ).withSources()\n # stack = stack.clean()\n R = []\n for idx in [ stack.items.length - 1 .. 0 ] by -1\n d = stack.items[ idx ]\n # debug '^2798^', ( k for k of d )\n s =\n # target_path: d.file\n relpath: d.fileRelative # fileShort\n native: d.native\n # is_nodejs: d.native\n is_other: d.thirdParty\n line: d.line\n column: d.column\n source: d.sourceLine\n error: d.error\n # for k in [ 'sourceLine', 'native', 'file', 'line', 'column', 'calleeShort', 'fileRelative', 'fileShort', 'fileName', 'thirdParty', 'name',]\n # debug k, rpr d[ k ]\n R.push s\n # info '\\n' + stack.asTable()\n return R\n\nshow_stacktracey = ( error ) ->\n for d in get_stacktracey error\n echo CND.steel '^44872^ ' + \"#{d.relpath} @ #{d.line}:#{d.column}\"\n ### NOTE errors:\n ENOENT: no such file or directory\n EISDIR: illegal operation on a directory, read\n 'Cannot read property 'originalPositionFor' of undefined'\n ###\n if d.error? then echo CND.red '^44873^ ' + ( d.error.message ? \"an error occurred\" )\n else echo CND.yellow '^44874^ ' + \"#{rpr d.source[ .. 100 ]}\"\n return null\n\n############################################################################################################\n############################################################################################################\n############################################################################################################\n\n\n############################################################################################################\nunless global[ Symbol.for 'cnd-exception-handler' ]?\n null\n global[ Symbol.for 'cnd-exception-handler' ] = true\n process.once 'uncaughtException', exit_handler\n process.once 'unhandledRejection', exit_handler\n\n # do =>\n # process.stderr.on 'data', ( data ) => debug \"^6863-1^ (stderr.on 'data'):\", rpr data\n # process.stdout.on 'data', ( data ) => debug \"^6863-2^ (stdout.on 'data'):\", rpr data\n # process.stderr.on 'end', => debug \"^6863-1^ (stderr.on 'end')\"\n # process.stdout.on 'end', => debug \"^6863-2^ (stdout.on 'end')\"\n # debug '^6456^'\n # echo \"^4564^ echo to stdout\"\n # warn \"^4564^ warn to stderr\"\n # process.stderr.write \"this goes to stderr\\n\"\n # process.stdout.write \"this goes to stdout\\n\"\n # process.on 'message', ( message ) -> debug \"^6863-3^' (process.on 'message'):\", rpr message\n # process.on 'warning', ( warning ) -> debug \"^6863-3^' (process.on 'warning'):\", rpr warning\n###\ncallsite.getThis() - returns the value of this\ncallsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.\ncallsite.getFunction() - returns the current function\ncallsite.getFunctionName() - returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.\ncallsite.getMethodName() - returns the name of the property of this or one of its prototypes that holds the current function\ncallsite.getFileName() - if this function was defined in a script returns the name of the script\ncallsite.getLineNumber() - if this function was defined in a script returns the current line number\ncallsite.getColumnNumber() - if this function was defined in a script returns the current column number\ncallsite.getEvalOrigin() - if this function was created using a call to eval returns a CallSite object representing the location where eval was called\ncallsite.isToplevel() - is this a toplevel invocation, that is, is this the global object?\ncallsite.isEval() - does this call take place in code defined by a call to eval?\ncallsite.isNative() - is this call in native V8 code?\ncallsite.isConstructor() - is this a constructor c\n###\n\n"
12
12
  ]
13
13
  }
package/package.json CHANGED
@@ -1,14 +1,11 @@
1
1
  {
2
2
  "name": "nodexh",
3
- "version": "1.1.0",
3
+ "version": "2.1.0",
4
4
  "description": "a wrapper around the `node` executable for better stacktraces with sourcemaps, sourcecode excerpts",
5
5
  "main": "lib/main.js",
6
6
  "bin": {
7
7
  "nodexh": "bin/nodexh"
8
8
  },
9
- "scripts": {
10
- "build": "coffee --map -o lib -c src"
11
- },
12
9
  "repository": {
13
10
  "type": "git",
14
11
  "url": "https://github.com/loveencounterflow/nodexh.git"
@@ -28,6 +25,11 @@
28
25
  "dependencies": {
29
26
  "cnd": "^9.1.0",
30
27
  "error-callsites": "^2.0.3",
31
- "load-source-map": "^2.0.0"
32
- }
33
- }
28
+ "load-source-map": "^2.0.0",
29
+ "stacktracey": "^2.0.14"
30
+ },
31
+ "scripts": {
32
+ "build": "coffee --map -o lib -c src"
33
+ },
34
+ "readme": "\n\n# NodeXH: NodeJS With a Better Exception Handler\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [What It Is](#what-it-is)\n- [How to Install](#how-to-install)\n- [How to Use](#how-to-use)\n- [What to Expect](#what-to-expect)\n- [Related](#related)\n- [To Do](#to-do)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n## What It Is\n\nNodeXH is a drop-in wrapper for the NodeJS executable hat provides better stacktraces.\n\n## How to Install\n\n`npm install -g nodexh`\n\n## How to Use\n\nUse `nodexh path/to/file.js` instead of `node path/to/file.js`, and you're good to go.\n\n## What to Expect\n\n* Stack trace items will be reversed, so most recent calls will be shown *last*, i.e. also closest to where\n the cursor of your terminal is.\n* Stack traces will show source contexts (3 lines by default) except where files can not be opened or are\n NodeJS internals.\n* Source code shown will honor sourcemaps, which is great when you're using the likes of CoffeeScript or\n TypeScript.\n* The error message will be repeated to avoid having to scroll up when stack traces get longer.\n* Colors!\n\n## Related\n\n* https://github.com/mozilla/source-map/\n* https://sokra.github.io/source-map-visualization/\n* https://medium.com/@nodejs/source-maps-in-node-js-482872b56116:\n * \"In v13.7.0 a public API was introduced for interacting with source\n maps.\"—[link](https://nodejs.org/dist/latest-v14.x/docs/api/all.html#modules_source_map_v3_support)\n * \"You can start using Node.js’ source map functionality today: make sure you have an up-to-date version\n of Node.js installed, and run your programs with the flag --enable-source-maps.\"\n\n## To Do\n\n* [ ] Add `error.name`, `error.code`; where `node` reports `TypeError: TEMPLATES.main_2 is not a function`,\n `nodexh` only reports `EXCEPTION: TEMPLATES.main_2 is not a function`\n* [ ] visually indicate spot of error (e.g. by reversing)\n* [ ] fix async stacktraces (probably not yet handled correctly; might be issue with `stackman`?)\n* [ ] consider [utf8ize-sourcemaps](https://github.com/twada/utf8ize-sourcemaps) in case there should be\n problems w/ 32bit characters\n* [ ] truncate long lines in context\n* [ ] offer capabilities of NodeXH as API so applications (such as test libraries) can easily retrieve\n source code, display source lines with contexts\n\n\n\n"
35
+ }
package/pnpm-lock.yaml ADDED
@@ -0,0 +1,76 @@
1
+ lockfileVersion: 5.3
2
+
3
+ specifiers:
4
+ cnd: ^9.1.0
5
+ error-callsites: ^2.0.3
6
+ load-source-map: ^2.0.0
7
+ stacktracey: ^2.0.14
8
+
9
+ dependencies:
10
+ cnd: 9.2.2
11
+ error-callsites: 2.0.4
12
+ load-source-map: 2.0.0
13
+ stacktracey: 2.1.8
14
+
15
+ packages:
16
+
17
+ /as-table/1.0.55:
18
+ resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
19
+ dependencies:
20
+ printable-characters: 1.0.42
21
+ dev: false
22
+
23
+ /cnd/9.2.2:
24
+ resolution: {integrity: sha512-F+/H+7luk4fZkvN0+MT0I2nwn80YM/EtfMttNUFxENR50XJH4g0KgQevzeyEJ8B6t6l8Tb4Xti6QAksa8DmePA==}
25
+ hasBin: true
26
+ dependencies:
27
+ jsx-number-format: 0.1.4
28
+ dev: false
29
+
30
+ /data-uri-to-buffer/2.0.2:
31
+ resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
32
+ dev: false
33
+
34
+ /error-callsites/2.0.4:
35
+ resolution: {integrity: sha512-V877Ch4FC4FN178fDK1fsrHN4I1YQIBdtjKrHh3BUHMnh3SMvwUVrqkaOgDpUuevgSNna0RBq6Ox9SGlxYrigA==}
36
+ engines: {node: '>=6.x'}
37
+ dev: false
38
+
39
+ /get-source/2.0.12:
40
+ resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
41
+ dependencies:
42
+ data-uri-to-buffer: 2.0.2
43
+ source-map: 0.6.1
44
+ dev: false
45
+
46
+ /jsx-number-format/0.1.4:
47
+ resolution: {integrity: sha512-uPc/Q90XqZoRE7Cu1OLFQB2cSrA2Dy8+okzPOtML8vbagNFDSipbndIPme+q0odBjEhL+wf3WH3Wo52was4Tsg==}
48
+ dev: false
49
+
50
+ /load-source-map/2.0.0:
51
+ resolution: {integrity: sha512-QNZzJ2wMrTmCdeobMuMNEXHN1QGk8HG6louEkzD/zwQ7EU2RarrzlhQ4GnUYEFzLhK+Jq7IGyF/qy+XYBSO7AQ==}
52
+ engines: {node: '>= 8'}
53
+ dependencies:
54
+ source-map: 0.7.3
55
+ dev: false
56
+
57
+ /printable-characters/1.0.42:
58
+ resolution: {integrity: sha1-Pxjpd6m9jrN/zE/1ZZ176Qhos9g=}
59
+ dev: false
60
+
61
+ /source-map/0.6.1:
62
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
63
+ engines: {node: '>=0.10.0'}
64
+ dev: false
65
+
66
+ /source-map/0.7.3:
67
+ resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==}
68
+ engines: {node: '>= 8'}
69
+ dev: false
70
+
71
+ /stacktracey/2.1.8:
72
+ resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==}
73
+ dependencies:
74
+ as-table: 1.0.55
75
+ get-source: 2.0.12
76
+ dev: false
package/src/main.coffee CHANGED
@@ -45,7 +45,8 @@ fetch_mapped_location = ( path, linenr, colnr ) ->
45
45
  sourcemap = await load_source_map path
46
46
  smp = sourcemap.originalPositionFor { line: linenr, column: colnr, }
47
47
  catch error
48
- warn '^7763-3^', "!!!!!!!!!!!!!!!!!", error.message
48
+ # warn '^7763-3^', "!!!!!!!!!!!!!!!!!", { path, }
49
+ # warn '^7763-3^', "!!!!!!!!!!!!!!!!!", error.message
49
50
  return { path, linenr, colnr, }
50
51
  #.........................................................................................................
51
52
  if ( smp? ) and ( smp.source? ) and ( smp.source isnt '' ) and ( smp.line? ) and ( smp.column? )
@@ -56,39 +57,39 @@ fetch_mapped_location = ( path, linenr, colnr ) ->
56
57
 
57
58
  #-----------------------------------------------------------------------------------------------------------
58
59
  get_context = ( path, linenr, colnr, width ) ->
59
- #.........................................................................................................
60
- try
61
- lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\n'
62
- delta = 1
63
- coldelta = 5
64
- ### TAINT use more meaningful limit like n times the terminal width, assuming default of 100 ###
65
- # effect = underline
66
- # effect = bold
67
- effect = reverse
68
- first_idx = Math.max 0, linenr - 1 - delta
69
- last_idx = Math.min lines.length - 1, linenr - 1 + delta
70
- R = []
71
- for line, idx in lines[ first_idx .. last_idx ]
72
- this_linenr = first_idx + idx + 1
73
- this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '
74
- if this_linenr is linenr
75
- c0 = colnr - 1
76
- c1 = colnr + coldelta
77
- hilite = effect line[ c0 ... c1 ]
78
- line = line[ ... c0 ] + hilite + line[ c1 .. ]
79
- if c1 > width
80
- width2 = Math.floor width / 2
81
- line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'
82
- else
83
- line = line[ .. width ]
84
- R.push "#{grey this_linenr_txt}#{cyan line}"
85
- else
86
- R.push "#{grey this_linenr_txt}#{grey line}"
87
- # R = R.join '\n'
88
- catch error
60
+ try return ( _get_context path, linenr, colnr, width ) catch error
89
61
  throw error unless error.code is 'ENOENT'
90
62
  # return [ ( red "!!! #{rpr error.message} !!!" ), ]
91
- return []
63
+ return []
64
+
65
+ #-----------------------------------------------------------------------------------------------------------
66
+ _get_context = ( path, linenr, colnr, width ) ->
67
+ lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\n'
68
+ delta = 1
69
+ coldelta = 5
70
+ effect = reverse
71
+ first_idx = Math.max 0, linenr - 1 - delta
72
+ last_idx = Math.min lines.length - 1, linenr - 1 + delta
73
+ R = []
74
+ for line, idx in lines[ first_idx .. last_idx ]
75
+ this_linenr = first_idx + idx + 1
76
+ this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '
77
+ if this_linenr isnt linenr
78
+ ### TAINT should adjust overlong context lines as well ###
79
+ R.push "#{grey this_linenr_txt}#{grey line}"
80
+ continue
81
+ ### TAINT perform line length adjustment, hiliting in dedicated method ###
82
+ c0 = colnr - 1
83
+ c1 = colnr + coldelta
84
+ hilite = effect line[ c0 ... c1 ]
85
+ line = line[ ... c0 ] + hilite + line[ c1 .. ]
86
+ if c1 > width
87
+ width2 = Math.floor width / 2
88
+ line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'
89
+ else
90
+ line = line[ .. width ]
91
+ R.push "#{grey this_linenr_txt}#{cyan line}"
92
+ # R = R.join '\n'
92
93
  return R
93
94
 
94
95
  #-----------------------------------------------------------------------------------------------------------
@@ -104,7 +105,7 @@ show_error_with_source_context = ( error, headline ) ->
104
105
  callsites = get_error_callsites error
105
106
  #.........................................................................................................
106
107
  if ( not callsites? ) or ( callsites.length is 0 )
107
- write_to_stderr CND.red CND.reverse "error has no associated callsites:"
108
+ write_to_stderr CND.red CND.reverse "^455756^ error has no associated callsites:"
108
109
  write_to_stderr CND.red CND.reverse rpr error
109
110
  return null
110
111
  #.........................................................................................................
@@ -120,40 +121,115 @@ show_error_with_source_context = ( error, headline ) ->
120
121
  linenr = callsite.getLineNumber()
121
122
  colnr = callsite.getColumnNumber()
122
123
  #.......................................................................................................
123
- if path.startsWith 'internal/'
124
- write_to_stderr arrowhead, grey "#{path} ##{linenr}"
124
+ if ( path.startsWith 'node:internal/' ) or ( path.startsWith 'internal/' )
125
+ write_to_stderr arrowhead, grey "#{path} @ #{linenr},#{colnr}"
125
126
  continue
126
127
  #.......................................................................................................
127
- # debug '^344463^', { relpath, linenr, colnr, }
128
128
  # write_to_stderr()
129
129
  # write_to_stderr steel bold reverse ( "#{relpath} ##{linenr}:" ).padEnd 108
130
+ fname = callsite.getFunctionName() ? callsite.getMethodName() ? null
130
131
  { path
131
132
  linenr
132
133
  colnr } = await fetch_mapped_location path, linenr, colnr
133
134
  relpath = PATH.relative process.cwd(), path
134
- write_to_stderr arrowhead, gold ( "#{relpath} @ #{linenr},#{colnr}: \x1b[38;05;234m".padEnd width, '—' )
135
+ if fname?
136
+ ### TAINT use proper methods to format with multiple colors ###
137
+ fname_txt = steel fname
138
+ width1 = width + ( fname_txt.length - fname.length )
139
+ write_to_stderr arrowhead, gold ( "#{relpath} @ #{linenr},#{colnr}: #{fname_txt}() \x1b[38;05;234m".padEnd width1, '—' )
140
+ else
141
+ write_to_stderr arrowhead, gold ( "#{relpath} @ #{linenr},#{colnr}: \x1b[38;05;234m".padEnd width, '—' )
135
142
  for context_line in await get_context path, linenr, colnr, width
136
143
  write_to_stderr arrowshaft, context_line
137
144
  alert '^77765-2^', reverse bold headline
138
- # if error?.message?
145
+ # urge "^94843^ error.stack:", rpr error.stack
146
+ # urge "^94843^ error.message:", rpr error.message
147
+ # urge "^94843^ error.code:", rpr error.code
148
+ # urge "^94843^ error.name:", rpr error.name
149
+ # urge "^94843^ error.type:", rpr error.type
150
+ # urge "^94843^ error.toString():", rpr error.toString()
151
+ # urge "^94843^ error:", rpr error
152
+ # CATALOGUING = require '../../multimix/lib/cataloguing'
153
+ # urge "^94843^", ( CATALOGUING.all_keys_of error )
139
154
  return null
140
155
 
141
156
  #-----------------------------------------------------------------------------------------------------------
142
- exit_handler = ( error ) ->
143
- message = ' EXCEPTION: ' + ( error?.message ? "an unrecoverable condition occurred" )
157
+ exit_handler = ( error, origin ) ->
158
+ ### TAINT origin never used ###
159
+ # show_stacktracey error
160
+ # debug '^4488^', error
161
+ # debug '^4488^', await origin
162
+ # return null
163
+ type = error.code ? error.name ? 'EXCEPTION'
164
+ message = " #{type}: " + ( error?.message ? "an unrecoverable condition occurred" )
144
165
  await show_error_with_source_context error, message
145
166
  setImmediate ( -> process.exit 111 )
146
- # process.exit 111
147
167
  return null
148
168
 
169
+ ############################################################################################################
170
+ ############################################################################################################
171
+ ############################################################################################################
172
+
173
+ get_stacktracey = ( error ) ->
174
+ StackTracey = require 'stacktracey'
175
+ stack = ( new StackTracey error ).withSources()
176
+ # stack = stack.clean()
177
+ R = []
178
+ for idx in [ stack.items.length - 1 .. 0 ] by -1
179
+ d = stack.items[ idx ]
180
+ # debug '^2798^', ( k for k of d )
181
+ s =
182
+ # target_path: d.file
183
+ relpath: d.fileRelative # fileShort
184
+ native: d.native
185
+ # is_nodejs: d.native
186
+ is_other: d.thirdParty
187
+ line: d.line
188
+ column: d.column
189
+ source: d.sourceLine
190
+ error: d.error
191
+ # for k in [ 'sourceLine', 'native', 'file', 'line', 'column', 'calleeShort', 'fileRelative', 'fileShort', 'fileName', 'thirdParty', 'name',]
192
+ # debug k, rpr d[ k ]
193
+ R.push s
194
+ # info '\n' + stack.asTable()
195
+ return R
196
+
197
+ show_stacktracey = ( error ) ->
198
+ for d in get_stacktracey error
199
+ echo CND.steel '^44872^ ' + "#{d.relpath} @ #{d.line}:#{d.column}"
200
+ ### NOTE errors:
201
+ ENOENT: no such file or directory
202
+ EISDIR: illegal operation on a directory, read
203
+ 'Cannot read property 'originalPositionFor' of undefined'
204
+ ###
205
+ if d.error? then echo CND.red '^44873^ ' + ( d.error.message ? "an error occurred" )
206
+ else echo CND.yellow '^44874^ ' + "#{rpr d.source[ .. 100 ]}"
207
+ return null
208
+
209
+ ############################################################################################################
210
+ ############################################################################################################
211
+ ############################################################################################################
149
212
 
150
213
 
151
214
  ############################################################################################################
152
215
  unless global[ Symbol.for 'cnd-exception-handler' ]?
216
+ null
153
217
  global[ Symbol.for 'cnd-exception-handler' ] = true
154
- process.on 'uncaughtException', exit_handler
155
- process.on 'unhandledRejection', exit_handler
218
+ process.once 'uncaughtException', exit_handler
219
+ process.once 'unhandledRejection', exit_handler
156
220
 
221
+ # do =>
222
+ # process.stderr.on 'data', ( data ) => debug "^6863-1^ (stderr.on 'data'):", rpr data
223
+ # process.stdout.on 'data', ( data ) => debug "^6863-2^ (stdout.on 'data'):", rpr data
224
+ # process.stderr.on 'end', => debug "^6863-1^ (stderr.on 'end')"
225
+ # process.stdout.on 'end', => debug "^6863-2^ (stdout.on 'end')"
226
+ # debug '^6456^'
227
+ # echo "^4564^ echo to stdout"
228
+ # warn "^4564^ warn to stderr"
229
+ # process.stderr.write "this goes to stderr\n"
230
+ # process.stdout.write "this goes to stdout\n"
231
+ # process.on 'message', ( message ) -> debug "^6863-3^' (process.on 'message'):", rpr message
232
+ # process.on 'warning', ( warning ) -> debug "^6863-3^' (process.on 'warning'):", rpr warning
157
233
  ###
158
234
  callsite.getThis() - returns the value of this
159
235
  callsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.