Created
December 17, 2024 11:50
-
-
Save paleite/6c69b7d7a3029350f45077d681b25e67 to your computer and use it in GitHub Desktop.
Error with circular references to JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Converts an Error object into a plain object with all its properties. | |
* It includes non-enumerable properties like "message", "name", and "stack". | |
* | |
* @param {Error} error - The Error object to convert. | |
* @returns {Object} A plain object containing the properties of the Error. | |
*/ | |
const convertErrorToPlainObject = (error) => | |
Object.fromEntries( | |
Object.getOwnPropertyNames(error).map((propertyName) => [ | |
propertyName, | |
error[propertyName], | |
]) | |
); | |
/** | |
* Creates a replacer function for JSON.stringify to handle circular references. | |
* If a circular reference is detected, the value is replaced with the string "[Circular]". | |
* | |
* @returns {(this: any, key: string, value: any) => any} A replacer function that can be used with JSON.stringify. | |
*/ | |
const createCircularReferenceReplacer = () => { | |
/** | |
* Tracks already visited objects to detect cycles. | |
* | |
* WeakSet is used to track already visited objects. WeakSet is preferred | |
* because it doesn't prevent garbage collection (unlike Set) and is | |
* specifically designed to hold objects only. | |
*/ | |
const seenObjects = new WeakSet(); | |
return (_key, value) => { | |
if (typeof value === "object" && value !== null) { | |
if (seenObjects.has(value)) { | |
return "[Circular]"; // Replace circular references with this placeholder. | |
} | |
seenObjects.add(value); // Mark this object as seen. | |
} | |
return value; | |
}; | |
}; | |
/** | |
* Serializes an Error object to a JSON string. | |
* It converts the Error into a plain object and ensures circular references are handled. | |
* | |
* @param {Error} error - The Error object to serialize. | |
* @returns {string} A JSON string representing the Error object. | |
*/ | |
const errorToJson = (error) => { | |
const handleCircularReferences = createCircularReferenceReplacer(); | |
const errorAsPlainObject = convertErrorToPlainObject(error); | |
return JSON.stringify(errorAsPlainObject, handleCircularReferences, 2); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const exampleError = new Error("Something bad happened"); | |
exampleError.self = exampleError; // Simulate a circular reference | |
console.log(errorToJson(exampleError)); | |
// Prints `{"stack":"Error: Something bad happened\n at <anonymous>:1:22","message":"Something bad happened","self":{"self":"[Circular]"}}` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment