DEV Community

Wes
Wes

Posted on • Originally published at goulet.dev on

How to Serialize Errors in Javascript

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 -> '{}'
Enter fullscreen mode Exit fullscreen mode

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!"
}
Enter fullscreen mode Exit fullscreen mode

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"}'
Enter fullscreen mode Exit fullscreen mode

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"}'
Enter fullscreen mode Exit fullscreen mode

Top comments (0)