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