Repository: nodejs/node
File: test/parallel/test-util-inspect.js (JavaScript)

Code before:
    '        at get bar (/foo/node_modules/bar.js:827:30))>],\n' +
    '    message: [Getter: <Inspection threw (Error: Oops\n' +
    '        at get foo (/foo/node_modules/foo.js:2:7)\n' +
    '        at get bar (/foo/node_modules/bar.js:827:30))>],\n' +
    '    cause: [Getter: <Inspection threw (Error: Oops\n' +
    '        at get foo (/foo/node_modules/foo.js:2:7)\n' +
    '        at get bar (/foo/node_modules/bar.js:827:30))>]\n' +
    '  })>]\n' +
    '}'
  );
}

// Property getter throwing an error with getters that throws recursivly.
{
  const terminalError = new Error('Oops');
  terminalError.stack = [
    'Error: Oops',
    '    at get foo (/foo/node_modules/foo.js:2:7)',
  ].join('\n');

  function getRecursiveThrowingError(recursions) {
    const badError = new Error();

    const innerError = recursions > 0 ?
      getRecursiveThrowingError(recursions - 1) :
      terminalError;

    const throwingGetter = {
      __proto__: null,
      get() {
        throw innerError;
      },
      configurable: true,
      enumerable: true,
    };

    Object.defineProperties(badError, {
      message: throwingGetter,
      stack: throwingGetter,
    });

    return badError;
  }

  const badRecursiveError = getRecursiveThrowingError(3);
  const thrower = {
    get foo() { throw badRecursiveError; }
  };

  assert.strictEqual(
    inspect(thrower, { getters: true, depth: 2 }),

Review comment (bug):
Actually, I would not want a terminal error, I'd like to test an infinite recursion to make sure we do not crash in this case (i.e. `inspect` has to give up at some point)

Code after:
    '    name: [Getter: <Inspection threw (Error: Oops\n' +
    '        at get foo (/foo/node_modules/foo.js:2:7)\n' +
    '        at get bar (/foo/node_modules/bar.js:827:30))>],\n' +
    '    message: [Getter: <Inspection threw (Error: Oops\n' +
    '        at get foo (/foo/node_modules/foo.js:2:7)\n' +
    '        at get bar (/foo/node_modules/bar.js:827:30))>],\n' +
    '    cause: [Getter: <Inspection threw (Error: Oops\n' +
    '        at get foo (/foo/node_modules/foo.js:2:7)\n' +
    '        at get bar (/foo/node_modules/bar.js:827:30))>]\n' +
    '  })>]\n' +
    '}'
  );
}

// Property getter throwing an error with getters that throws recursivly.
{
  const recursivelyThrowingErrorDesc = {
    __proto__: null,
    // eslint-disable-next-line no-restricted-syntax
    get() { throw createRecursivelyThrowingError(); },
    configurable: true,
    enumerable: true,
  };
  const createRecursivelyThrowingError = () =>
    Object.defineProperties(new Error(), {
      cause: recursivelyThrowingErrorDesc,
      name: recursivelyThrowingErrorDesc,
      message: recursivelyThrowingErrorDesc,
      stack: recursivelyThrowingErrorDesc,
    });
  const thrower = Object.defineProperty({}, 'foo', recursivelyThrowingErrorDesc);

  assert.strictEqual(
    inspect(thrower, { getters: true, depth: 1 }),
    '{\n' +
    '  foo: [Getter: <Inspection threw ([object Error] {\n' +
    '    stack: [Getter/Setter: <Inspection threw ([Error])>],\n' +
    '    cause: [Getter: <Inspection threw ([Error])>],\n' +
    '    name: [Getter: <Inspection threw ([Error])>],\n' +
    '    message: [Getter: <Inspection threw ([Error])>]\n' +
    '  })>]\n' +
    '}'
  );

  [{ getters: true, depth: 2 }, { getters: true }].forEach((options) => {
    assert.strictEqual(
      inspect(thrower, options),
      '{\n' +
      '  foo: [Getter: <Inspection threw ([object Error] {\n' +
      '    stack: [Getter/Setter: <Inspection threw ([object Error] {\n' +
      '      stack: [Getter/Setter: <Inspection threw ([Error])>],\n' +