11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst Buffer = require('buffer').Buffer;
41cb0ef41Sopenharmony_ciconst {
51cb0ef41Sopenharmony_ci  ArrayPrototypeForEach,
61cb0ef41Sopenharmony_ci  Error,
71cb0ef41Sopenharmony_ci  EvalError,
81cb0ef41Sopenharmony_ci  FunctionPrototypeCall,
91cb0ef41Sopenharmony_ci  ObjectAssign,
101cb0ef41Sopenharmony_ci  ObjectCreate,
111cb0ef41Sopenharmony_ci  ObjectDefineProperty,
121cb0ef41Sopenharmony_ci  ObjectGetOwnPropertyDescriptor,
131cb0ef41Sopenharmony_ci  ObjectGetOwnPropertyNames,
141cb0ef41Sopenharmony_ci  ObjectGetPrototypeOf,
151cb0ef41Sopenharmony_ci  ObjectKeys,
161cb0ef41Sopenharmony_ci  ObjectPrototypeToString,
171cb0ef41Sopenharmony_ci  RangeError,
181cb0ef41Sopenharmony_ci  ReferenceError,
191cb0ef41Sopenharmony_ci  SafeSet,
201cb0ef41Sopenharmony_ci  StringFromCharCode,
211cb0ef41Sopenharmony_ci  StringPrototypeSubstring,
221cb0ef41Sopenharmony_ci  SymbolToStringTag,
231cb0ef41Sopenharmony_ci  SyntaxError,
241cb0ef41Sopenharmony_ci  SymbolFor,
251cb0ef41Sopenharmony_ci  TypeError,
261cb0ef41Sopenharmony_ci  TypedArrayPrototypeGetBuffer,
271cb0ef41Sopenharmony_ci  TypedArrayPrototypeGetByteOffset,
281cb0ef41Sopenharmony_ci  TypedArrayPrototypeGetByteLength,
291cb0ef41Sopenharmony_ci  URIError,
301cb0ef41Sopenharmony_ci} = primordials;
311cb0ef41Sopenharmony_ciconst { inspect: { custom: customInspectSymbol } } = require('util');
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciconst kSerializedError = 0;
341cb0ef41Sopenharmony_ciconst kSerializedObject = 1;
351cb0ef41Sopenharmony_ciconst kInspectedError = 2;
361cb0ef41Sopenharmony_ciconst kInspectedSymbol = 3;
371cb0ef41Sopenharmony_ciconst kCustomInspectedObject = 4;
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ciconst kSymbolStringLength = 'Symbol('.length;
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciconst errors = {
421cb0ef41Sopenharmony_ci  Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError,
431cb0ef41Sopenharmony_ci};
441cb0ef41Sopenharmony_ciconst errorConstructorNames = new SafeSet(ObjectKeys(errors));
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cifunction TryGetAllProperties(object, target = object) {
471cb0ef41Sopenharmony_ci  const all = ObjectCreate(null);
481cb0ef41Sopenharmony_ci  if (object === null)
491cb0ef41Sopenharmony_ci    return all;
501cb0ef41Sopenharmony_ci  ObjectAssign(all,
511cb0ef41Sopenharmony_ci               TryGetAllProperties(ObjectGetPrototypeOf(object), target));
521cb0ef41Sopenharmony_ci  const keys = ObjectGetOwnPropertyNames(object);
531cb0ef41Sopenharmony_ci  ArrayPrototypeForEach(keys, (key) => {
541cb0ef41Sopenharmony_ci    let descriptor;
551cb0ef41Sopenharmony_ci    try {
561cb0ef41Sopenharmony_ci      // TODO: create a null-prototype descriptor with needed properties only
571cb0ef41Sopenharmony_ci      descriptor = ObjectGetOwnPropertyDescriptor(object, key);
581cb0ef41Sopenharmony_ci    } catch { return; }
591cb0ef41Sopenharmony_ci    const getter = descriptor.get;
601cb0ef41Sopenharmony_ci    if (getter && key !== '__proto__') {
611cb0ef41Sopenharmony_ci      try {
621cb0ef41Sopenharmony_ci        descriptor.value = FunctionPrototypeCall(getter, target);
631cb0ef41Sopenharmony_ci        delete descriptor.get;
641cb0ef41Sopenharmony_ci        delete descriptor.set;
651cb0ef41Sopenharmony_ci      } catch {
661cb0ef41Sopenharmony_ci        // Continue regardless of error.
671cb0ef41Sopenharmony_ci      }
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci    if (key === 'cause') {
701cb0ef41Sopenharmony_ci      descriptor.value = serializeError(descriptor.value);
711cb0ef41Sopenharmony_ci      all[key] = descriptor;
721cb0ef41Sopenharmony_ci    } else if ('value' in descriptor &&
731cb0ef41Sopenharmony_ci            typeof descriptor.value !== 'function' && typeof descriptor.value !== 'symbol') {
741cb0ef41Sopenharmony_ci      all[key] = descriptor;
751cb0ef41Sopenharmony_ci    }
761cb0ef41Sopenharmony_ci  });
771cb0ef41Sopenharmony_ci  return all;
781cb0ef41Sopenharmony_ci}
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_cifunction GetConstructors(object) {
811cb0ef41Sopenharmony_ci  const constructors = [];
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  for (let current = object;
841cb0ef41Sopenharmony_ci    current !== null;
851cb0ef41Sopenharmony_ci    current = ObjectGetPrototypeOf(current)) {
861cb0ef41Sopenharmony_ci    const desc = ObjectGetOwnPropertyDescriptor(current, 'constructor');
871cb0ef41Sopenharmony_ci    if (desc && desc.value) {
881cb0ef41Sopenharmony_ci      ObjectDefineProperty(constructors, constructors.length, {
891cb0ef41Sopenharmony_ci        __proto__: null,
901cb0ef41Sopenharmony_ci        value: desc.value, enumerable: true,
911cb0ef41Sopenharmony_ci      });
921cb0ef41Sopenharmony_ci    }
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  return constructors;
961cb0ef41Sopenharmony_ci}
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_cifunction GetName(object) {
991cb0ef41Sopenharmony_ci  const desc = ObjectGetOwnPropertyDescriptor(object, 'name');
1001cb0ef41Sopenharmony_ci  return desc && desc.value;
1011cb0ef41Sopenharmony_ci}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_cilet internalUtilInspect;
1041cb0ef41Sopenharmony_cifunction inspect(...args) {
1051cb0ef41Sopenharmony_ci  if (!internalUtilInspect) {
1061cb0ef41Sopenharmony_ci    internalUtilInspect = require('internal/util/inspect');
1071cb0ef41Sopenharmony_ci  }
1081cb0ef41Sopenharmony_ci  return internalUtilInspect.inspect(...args);
1091cb0ef41Sopenharmony_ci}
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_cilet serialize;
1121cb0ef41Sopenharmony_cifunction serializeError(error) {
1131cb0ef41Sopenharmony_ci  if (!serialize) serialize = require('v8').serialize;
1141cb0ef41Sopenharmony_ci  if (typeof error === 'symbol') {
1151cb0ef41Sopenharmony_ci    return Buffer.from(StringFromCharCode(kInspectedSymbol) + inspect(error), 'utf8');
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci  try {
1181cb0ef41Sopenharmony_ci    if (typeof error === 'object' &&
1191cb0ef41Sopenharmony_ci        ObjectPrototypeToString(error) === '[object Error]') {
1201cb0ef41Sopenharmony_ci      const constructors = GetConstructors(error);
1211cb0ef41Sopenharmony_ci      for (let i = 0; i < constructors.length; i++) {
1221cb0ef41Sopenharmony_ci        const name = GetName(constructors[i]);
1231cb0ef41Sopenharmony_ci        if (errorConstructorNames.has(name)) {
1241cb0ef41Sopenharmony_ci          const serialized = serialize({
1251cb0ef41Sopenharmony_ci            constructor: name,
1261cb0ef41Sopenharmony_ci            properties: TryGetAllProperties(error),
1271cb0ef41Sopenharmony_ci          });
1281cb0ef41Sopenharmony_ci          return Buffer.concat([Buffer.from([kSerializedError]), serialized]);
1291cb0ef41Sopenharmony_ci        }
1301cb0ef41Sopenharmony_ci      }
1311cb0ef41Sopenharmony_ci    }
1321cb0ef41Sopenharmony_ci  } catch {
1331cb0ef41Sopenharmony_ci    // Continue regardless of error.
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci  try {
1361cb0ef41Sopenharmony_ci    if (error != null && customInspectSymbol in error) {
1371cb0ef41Sopenharmony_ci      return Buffer.from(StringFromCharCode(kCustomInspectedObject) + inspect(error), 'utf8');
1381cb0ef41Sopenharmony_ci    }
1391cb0ef41Sopenharmony_ci  } catch {
1401cb0ef41Sopenharmony_ci    // Continue regardless of error.
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci  try {
1431cb0ef41Sopenharmony_ci    const serialized = serialize(error);
1441cb0ef41Sopenharmony_ci    return Buffer.concat([Buffer.from([kSerializedObject]), serialized]);
1451cb0ef41Sopenharmony_ci  } catch {
1461cb0ef41Sopenharmony_ci    // Continue regardless of error.
1471cb0ef41Sopenharmony_ci  }
1481cb0ef41Sopenharmony_ci  return Buffer.from(StringFromCharCode(kInspectedError) + inspect(error), 'utf8');
1491cb0ef41Sopenharmony_ci}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_cifunction fromBuffer(error) {
1521cb0ef41Sopenharmony_ci  return Buffer.from(TypedArrayPrototypeGetBuffer(error),
1531cb0ef41Sopenharmony_ci                     TypedArrayPrototypeGetByteOffset(error) + 1,
1541cb0ef41Sopenharmony_ci                     TypedArrayPrototypeGetByteLength(error) - 1);
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_cilet deserialize;
1581cb0ef41Sopenharmony_cifunction deserializeError(error) {
1591cb0ef41Sopenharmony_ci  if (!deserialize) deserialize = require('v8').deserialize;
1601cb0ef41Sopenharmony_ci  switch (error[0]) {
1611cb0ef41Sopenharmony_ci    case kSerializedError: {
1621cb0ef41Sopenharmony_ci      const { constructor, properties } = deserialize(error.subarray(1));
1631cb0ef41Sopenharmony_ci      const ctor = errors[constructor];
1641cb0ef41Sopenharmony_ci      ObjectDefineProperty(properties, SymbolToStringTag, {
1651cb0ef41Sopenharmony_ci        __proto__: null,
1661cb0ef41Sopenharmony_ci        value: { __proto__: null, value: 'Error', configurable: true },
1671cb0ef41Sopenharmony_ci        enumerable: true,
1681cb0ef41Sopenharmony_ci      });
1691cb0ef41Sopenharmony_ci      if ('cause' in properties && 'value' in properties.cause) {
1701cb0ef41Sopenharmony_ci        properties.cause.value = deserializeError(properties.cause.value);
1711cb0ef41Sopenharmony_ci      }
1721cb0ef41Sopenharmony_ci      return ObjectCreate(ctor.prototype, properties);
1731cb0ef41Sopenharmony_ci    }
1741cb0ef41Sopenharmony_ci    case kSerializedObject:
1751cb0ef41Sopenharmony_ci      return deserialize(error.subarray(1));
1761cb0ef41Sopenharmony_ci    case kInspectedError:
1771cb0ef41Sopenharmony_ci      return fromBuffer(error).toString('utf8');
1781cb0ef41Sopenharmony_ci    case kInspectedSymbol: {
1791cb0ef41Sopenharmony_ci      const buf = fromBuffer(error);
1801cb0ef41Sopenharmony_ci      return SymbolFor(StringPrototypeSubstring(buf.toString('utf8'), kSymbolStringLength, buf.length - 1));
1811cb0ef41Sopenharmony_ci    }
1821cb0ef41Sopenharmony_ci    case kCustomInspectedObject:
1831cb0ef41Sopenharmony_ci      return {
1841cb0ef41Sopenharmony_ci        __proto__: null,
1851cb0ef41Sopenharmony_ci        [customInspectSymbol]: () => fromBuffer(error).toString('utf8'),
1861cb0ef41Sopenharmony_ci      };
1871cb0ef41Sopenharmony_ci  }
1881cb0ef41Sopenharmony_ci  require('assert').fail('This should not happen');
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_cimodule.exports = { serializeError, deserializeError };
192