11cb0ef41Sopenharmony_ci// Flags: --expose-internals
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_cirequire('../common');
41cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
51cb0ef41Sopenharmony_ciconst assert = require('assert');
61cb0ef41Sopenharmony_ciconst internalUtil = require('internal/util');
71cb0ef41Sopenharmony_ciconst { internalBinding } = require('internal/test/binding');
81cb0ef41Sopenharmony_ciconst {
91cb0ef41Sopenharmony_ci  privateSymbols: {
101cb0ef41Sopenharmony_ci    arrow_message_private_symbol,
111cb0ef41Sopenharmony_ci    decorated_private_symbol,
121cb0ef41Sopenharmony_ci  }
131cb0ef41Sopenharmony_ci} = internalBinding('util');
141cb0ef41Sopenharmony_ciconst spawnSync = require('child_process').spawnSync;
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciconst decorateErrorStack = internalUtil.decorateErrorStack;
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci// Verify that decorateErrorStack does not throw with non-objects.
191cb0ef41Sopenharmony_cidecorateErrorStack();
201cb0ef41Sopenharmony_cidecorateErrorStack(null);
211cb0ef41Sopenharmony_cidecorateErrorStack(1);
221cb0ef41Sopenharmony_cidecorateErrorStack(true);
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci// Verify that a stack property is not added to non-Errors.
251cb0ef41Sopenharmony_ciconst obj = {};
261cb0ef41Sopenharmony_cidecorateErrorStack(obj);
271cb0ef41Sopenharmony_ciassert.strictEqual(obj.stack, undefined);
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci// Verify that the stack is decorated when possible.
301cb0ef41Sopenharmony_cifunction checkStack(stack) {
311cb0ef41Sopenharmony_ci  // Matching only on a minimal piece of the stack because the string will vary
321cb0ef41Sopenharmony_ci  // greatly depending on the JavaScript engine. V8 includes `;` because it
331cb0ef41Sopenharmony_ci  // displays the line of code (`var foo bar;`) that is causing a problem.
341cb0ef41Sopenharmony_ci  // ChakraCore does not display the line of code but includes `;` in the phrase
351cb0ef41Sopenharmony_ci  // `Expected ';' `.
361cb0ef41Sopenharmony_ci  assert.match(stack, /;/g);
371cb0ef41Sopenharmony_ci  // Test that it's a multiline string.
381cb0ef41Sopenharmony_ci  assert.match(stack, /\n/g);
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_cilet err;
411cb0ef41Sopenharmony_ciconst badSyntaxPath =
421cb0ef41Sopenharmony_ci  fixtures.path('syntax', 'bad_syntax').replace(/\\/g, '\\\\');
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_citry {
451cb0ef41Sopenharmony_ci  require(badSyntaxPath);
461cb0ef41Sopenharmony_ci} catch (e) {
471cb0ef41Sopenharmony_ci  err = e;
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ciassert(typeof err, 'object');
511cb0ef41Sopenharmony_cicheckStack(err.stack);
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci// Verify that the stack is only decorated once.
541cb0ef41Sopenharmony_cidecorateErrorStack(err);
551cb0ef41Sopenharmony_cidecorateErrorStack(err);
561cb0ef41Sopenharmony_cicheckStack(err.stack);
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci// Verify that the stack is only decorated once for uncaught exceptions.
591cb0ef41Sopenharmony_ciconst args = [
601cb0ef41Sopenharmony_ci  '-e',
611cb0ef41Sopenharmony_ci  `require(${JSON.stringify(badSyntaxPath)})`,
621cb0ef41Sopenharmony_ci];
631cb0ef41Sopenharmony_ciconst result = spawnSync(process.argv[0], args, { encoding: 'utf8' });
641cb0ef41Sopenharmony_cicheckStack(result.stderr);
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci// Verify that the stack is unchanged when there is no arrow message.
671cb0ef41Sopenharmony_cierr = new Error('foo');
681cb0ef41Sopenharmony_cilet originalStack = err.stack;
691cb0ef41Sopenharmony_cidecorateErrorStack(err);
701cb0ef41Sopenharmony_ciassert.strictEqual(originalStack, err.stack);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci// Verify that the arrow message is added to the start of the stack when it
731cb0ef41Sopenharmony_ci// exists.
741cb0ef41Sopenharmony_ciconst arrowMessage = 'arrow_message';
751cb0ef41Sopenharmony_cierr = new Error('foo');
761cb0ef41Sopenharmony_cioriginalStack = err.stack;
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_cierr[arrow_message_private_symbol] = arrowMessage;
791cb0ef41Sopenharmony_cidecorateErrorStack(err);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ciassert.strictEqual(err.stack, `${arrowMessage}${originalStack}`);
821cb0ef41Sopenharmony_ciassert.strictEqual(err[decorated_private_symbol], true);
83