Don't use a simple JSON.stringify
If you want to serialize an Error in Javascript you might be tempted to simply use JSON.stringify
, but that won't be very helpful.
const error = new Error("Something went wrong"); const serialized = JSON.stringify(error); // serialized -> '{}'
Normalize the error
Instead what I like to do is "normalize" the error (in case it's not actually an Error
object) and then use the error message:
/** * @param {unknown} error * @returns {Error} */ export function normalizeError(error) { if (typeof error === "object" && error instanceof Error) { return error; } else if (typeof error === "string") { return new Error(error); } // else turn this unknown thing into a string return new Error(JSON.stringify(error)); } // NOW I CAN CATCH ERRORS... try { throw new Error("Something went wrong"); } catch (error) { const normalized = normalizeError(error); const serialized = normalized.message; // serialized -> "Something went wrong" } // AND ANYTHING ELSE try { throw "Who throws a string? ME!"; } catch (error) { const normalized = normalizeError(error); const serialized = normalized.message; // serialized -> "Who throws a string? ME!" }
Alternative: Use overloaded JSON.stringify
If you know you are dealing with an Error
object (so you don't need to normalize it) then you can use JSON.stringify
with a second argument to tell JSON stringify which properties to enumerate:
const error = new Error("Something went wrong"); const serialized = JSON.stringify(error, Object.getOwnPropertyNames(error)); // serialized -> '{"stack":"Error: Something went wrong\\n at REPL9:1:13\\n at Script.runInThisContext (node:vm:131:12)\\n at REPLServer.defaultEval (node:repl:522:29)\\n at bound (node:domain:416:15)\\n at REPLServer.runBound [as eval] (node:domain:427:12)\\n at REPLServer.onLine (node:repl:844:10)\\n at REPLServer.emit (node:events:390:22)\\n at REPLServer.EventEmitter.emit (node:domain:470:12)\\n at REPLServer.Interface._onLine (node:readline:418:10)\\n at REPLServer.Interface._line (node:readline:763:8)","message":"Something went wrong"}'
If you don't want the stack in there you can just list an array of the properties you want:
const error = new Error("Something went wrong"); const serialized = JSON.stringify(error, ["message", "name"]); // serialized -> '{"message":"Something went wrong", "name": "Error"}'
Top comments (0)