diff options
Diffstat (limited to 'desktop/node_modules/serialize-error/index.js')
-rw-r--r-- | desktop/node_modules/serialize-error/index.js | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/desktop/node_modules/serialize-error/index.js b/desktop/node_modules/serialize-error/index.js new file mode 100644 index 0000000..508c6a2 --- /dev/null +++ b/desktop/node_modules/serialize-error/index.js @@ -0,0 +1,101 @@ +'use strict'; + +class NonError extends Error { + constructor(message) { + super(NonError._prepareSuperMessage(message)); + Object.defineProperty(this, 'name', { + value: 'NonError', + configurable: true, + writable: true + }); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, NonError); + } + } + + static _prepareSuperMessage(message) { + try { + return JSON.stringify(message); + } catch (_) { + return String(message); + } + } +} + +const commonProperties = [ + {property: 'name', enumerable: false}, + {property: 'message', enumerable: false}, + {property: 'stack', enumerable: false}, + {property: 'code', enumerable: true} +]; + +const destroyCircular = ({from, seen, to_, forceEnumerable}) => { + const to = to_ || (Array.isArray(from) ? [] : {}); + + seen.push(from); + + for (const [key, value] of Object.entries(from)) { + if (typeof value === 'function') { + continue; + } + + if (!value || typeof value !== 'object') { + to[key] = value; + continue; + } + + if (!seen.includes(from[key])) { + to[key] = destroyCircular({from: from[key], seen: seen.slice(), forceEnumerable}); + continue; + } + + to[key] = '[Circular]'; + } + + for (const {property, enumerable} of commonProperties) { + if (typeof from[property] === 'string') { + Object.defineProperty(to, property, { + value: from[property], + enumerable: forceEnumerable ? true : enumerable, + configurable: true, + writable: true + }); + } + } + + return to; +}; + +const serializeError = value => { + if (typeof value === 'object' && value !== null) { + return destroyCircular({from: value, seen: [], forceEnumerable: true}); + } + + // People sometimes throw things besides Error objects… + if (typeof value === 'function') { + // `JSON.stringify()` discards functions. We do too, unless a function is thrown directly. + return `[Function: ${(value.name || 'anonymous')}]`; + } + + return value; +}; + +const deserializeError = value => { + if (value instanceof Error) { + return value; + } + + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + const newError = new Error(); + destroyCircular({from: value, seen: [], to_: newError}); + return newError; + } + + return new NonError(value); +}; + +module.exports = { + serializeError, + deserializeError +}; |