jsrosetta

Error handling

Error Handling and try/catch

How Node.js's throw and try/catch/finally compare to error values in Go, Result in Rust, throws in Swift, and exceptions in Java.

JavaScript lets you throw anything, anywhere, and the caller has no way of knowing a function might throw. The languages below split into two camps:

  • Errors are return values: Go, Rust. The caller is forced to handle them.
  • Exceptions: Swift, Java. Similar to JavaScript, but stricter about types.

Defining, throwing, and catching errors

class NotFoundError extends Error {
  constructor(id) {
    super(`user ${id} not found`);
    this.name = "NotFoundError";
  }
}
 
function findUser(id) {
  if (id !== 1) throw new NotFoundError(id);
  return { id, name: "neko" };
}
 
try {
  const user = findUser(2);
  console.log(user.name);
} catch (err) {
  if (err instanceof NotFoundError) console.error(err.message);
  else throw err;
} finally {
  console.log("done");
}

Propagating errors upward (rethrow)

In JavaScript, an uncaught error automatically propagates up to the caller. Go and Rust make you write that out explicitly:

function greet(id) {
  const user = findUser(id); // the error propagates automatically
  return `hi ${user.name}`;
}

Falling back to a default value on error

let name;
try {
  name = findUser(2).name;
} catch {
  name = "guest";
}

Reference: github.com/miguelmota/golang-for-nodejs-developers#errors