|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +constBuffer=require('buffer').Buffer; |
| 4 | +const{ serialize, deserialize }=require('v8'); |
| 5 | +const{ SafeSet }=require('internal/safe_globals'); |
| 6 | + |
| 7 | +constkSerializedError=0; |
| 8 | +constkSerializedObject=1; |
| 9 | +constkInspectedError=2; |
| 10 | + |
| 11 | +constGetPrototypeOf=Object.getPrototypeOf; |
| 12 | +constGetOwnPropertyDescriptor=Object.getOwnPropertyDescriptor; |
| 13 | +constGetOwnPropertyNames=Object.getOwnPropertyNames; |
| 14 | +constDefineProperty=Object.defineProperty; |
| 15 | +constAssign=Object.assign; |
| 16 | +constObjectPrototypeToString= |
| 17 | +Function.prototype.call.bind(Object.prototype.toString); |
| 18 | +constForEach=Function.prototype.call.bind(Array.prototype.forEach); |
| 19 | +constCall=Function.prototype.call.bind(Function.prototype.call); |
| 20 | + |
| 21 | +consterrors={ |
| 22 | + Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError |
| 23 | +}; |
| 24 | +consterrorConstructorNames=newSafeSet(Object.keys(errors)); |
| 25 | + |
| 26 | +functionTryGetAllProperties(object,target=object){ |
| 27 | +constall=Object.create(null); |
| 28 | +if(object===null) |
| 29 | +returnall; |
| 30 | +Assign(all,TryGetAllProperties(GetPrototypeOf(object),target)); |
| 31 | +constkeys=GetOwnPropertyNames(object); |
| 32 | +ForEach(keys,(key)=>{ |
| 33 | +constdescriptor=GetOwnPropertyDescriptor(object,key); |
| 34 | +constgetter=descriptor.get; |
| 35 | +if(getter&&key!=='__proto__'){ |
| 36 | +try{ |
| 37 | +descriptor.value=Call(getter,target); |
| 38 | +}catch{} |
| 39 | +} |
| 40 | +if('value'indescriptor&&typeofdescriptor.value!=='function'){ |
| 41 | +deletedescriptor.get; |
| 42 | +deletedescriptor.set; |
| 43 | +all[key]=descriptor; |
| 44 | +} |
| 45 | +}); |
| 46 | +returnall; |
| 47 | +} |
| 48 | + |
| 49 | +functionGetConstructors(object){ |
| 50 | +constconstructors=[]; |
| 51 | + |
| 52 | +for(varcurrent=object; |
| 53 | +current!==null; |
| 54 | +current=GetPrototypeOf(current)){ |
| 55 | +constdesc=GetOwnPropertyDescriptor(current,'constructor'); |
| 56 | +if(desc&&desc.value){ |
| 57 | +DefineProperty(constructors,constructors.length,{ |
| 58 | +value: desc.value,enumerable: true |
| 59 | +}); |
| 60 | +} |
| 61 | +} |
| 62 | + |
| 63 | +returnconstructors; |
| 64 | +} |
| 65 | + |
| 66 | +functionGetName(object){ |
| 67 | +constdesc=GetOwnPropertyDescriptor(object,'name'); |
| 68 | +returndesc&&desc.value; |
| 69 | +} |
| 70 | + |
| 71 | +letutil; |
| 72 | +functionlazyUtil(){ |
| 73 | +if(!util) |
| 74 | +util=require('util'); |
| 75 | +returnutil; |
| 76 | +} |
| 77 | + |
| 78 | +functionserializeError(error){ |
| 79 | +try{ |
| 80 | +if(typeoferror==='object'&& |
| 81 | +ObjectPrototypeToString(error)==='[object Error]'){ |
| 82 | +constconstructors=GetConstructors(error); |
| 83 | +for(vari=constructors.length-1;i>=0;i--){ |
| 84 | +constname=GetName(constructors[i]); |
| 85 | +if(errorConstructorNames.has(name)){ |
| 86 | +try{error.stack;}catch{} |
| 87 | +constserialized=serialize({ |
| 88 | +constructor: name, |
| 89 | +properties: TryGetAllProperties(error) |
| 90 | +}); |
| 91 | +returnBuffer.concat([Buffer.from([kSerializedError]),serialized]); |
| 92 | +} |
| 93 | +} |
| 94 | +} |
| 95 | +}catch{} |
| 96 | +try{ |
| 97 | +constserialized=serialize(error); |
| 98 | +returnBuffer.concat([Buffer.from([kSerializedObject]),serialized]); |
| 99 | +}catch{} |
| 100 | +returnBuffer.concat([Buffer.from([kInspectedError]), |
| 101 | +Buffer.from(lazyUtil().inspect(error),'utf8')]); |
| 102 | +} |
| 103 | + |
| 104 | +functiondeserializeError(error){ |
| 105 | +switch(error[0]){ |
| 106 | +casekSerializedError: |
| 107 | +const{ constructor, properties }=deserialize(error.subarray(1)); |
| 108 | +constctor=errors[constructor]; |
| 109 | +returnObject.create(ctor.prototype,properties); |
| 110 | +casekSerializedObject: |
| 111 | +returndeserialize(error.subarray(1)); |
| 112 | +casekInspectedError: |
| 113 | +constbuf=Buffer.from(error.buffer, |
| 114 | +error.byteOffset+1, |
| 115 | +error.byteLength-1); |
| 116 | +returnbuf.toString('utf8'); |
| 117 | +} |
| 118 | +require('assert').fail('This should not happen'); |
| 119 | +} |
| 120 | + |
| 121 | +module.exports={ serializeError, deserializeError }; |
0 commit comments