TLDR
throw new Error('problem')
captures a number of properties of the place where the error happened.
throw 'problem'
does not
new Error('message')
captures the execution stack + others
Using an Error object allows you to capture the execution stack at the point where you throw the error. So when the error gets passed up the error handling tree, so does this stack snapshot.
So inserting throw "test error"
somewhere in my codebase results in:
Whereas throw new Error('test error')
results in:
You can see that the native Error object captures the stack at the point I throw the error and makes it available to whatever captures the error. That makes it easier for me to trace the problem when I'm debugging it.
In addition to that it also captures properties such as fileName
, lineNumber
and columnNumber
.
Exception loggers will capture the stack trace for you
In this case the stack is being printed into the browser console but if you're using Javascript error logging tools like Appsignal or Bugsnag then that stack will also be available in them too. If you inspect the error object you can access the stack snapshot directly:
err = new Error('test')
err.stack
When to use which error format
Exceptions you plan to catch can be simple: throw 'problem'
If the error you are throwing is an expected error that you plan to catch and handle then you're not going to get much use out of the stack snapshot.
So, let's say you're using an http service and it returns a 500 HTTP code. You may treat this as an error which you throw {responseCode=500}
and then subsequently catch and handle.
Exceptions you don't plan to catch should use new Error('problem')
When you're throwing an error because something unexpected or out-of-bounds has happened in the application, let's say the local datastore is corrupted, you might be in a situation where you don't want to handle it, but you do want to flag it. In this case it's a good time to use the Error object so you have that stack snapshot.
By using throw new Error('Datastore is corrupted')
it'll be easier to trace your way back to what's happened.
Error
s – Bergicreates and initializes a new Error object when called as a function rather than as a constructor. Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments.
Spec in tc39.es/ecma262/#sec-error-constructor – kitimenpolku