getFullErrorStack = function (err, seen) {
  if (seen && seen.has(err)) {
    return { message: '', msg: '<circular>', stack: '' };
  }

  var message;

  if (typeof err.inspect === 'function') {
    message = err.inspect() + '';
  } else if (err.message && typeof err.message.toString === 'function') {
    message = err.message + '';
  } else {
    message = '';
  }

  var msg;
  var stack = err.stack || message;
  var index = message ? stack.indexOf(message) : -1;

  if (index === -1) {
    msg = message;
  } else {
    index += message.length;
    msg = stack.slice(0, index);
    // remove msg from stack
    stack = stack.slice(index + 1);

    if (err.cause) {
      seen = seen || new Set();
      seen.add(err);
      const causeStack = getFullErrorStack(err.cause, seen)
      stack += '\n   Caused by: ' + causeStack.msg + (causeStack.stack ? '\n' + causeStack.stack : '');
    }
  }

  return {
    message,
    msg,
    stack
  };
}
Traverses err.cause and returns all stack traces

@private
@param {Error} err
@param {Set<Error>} [seen]
@return {FullErrorStack}