Each of the commentators has provided a thorough response to your query, but let's illustrate the significance with an example. Consider the code snippet below:
Promise.reject();
setTimeout(() => console.log('hello'), 1000);
On the surface, this code appears harmless - it includes a promise rejection that goes unhandled, and after one second, the program will log 'hello'
.
In a browser environment, this behavior is exactly what you can expect - an "uncaught promise rejection" error will be logged, but otherwise, it will be disregarded.
However, in NodeJS (from Node v15 onwards), unhandled promise rejections are considered a HARD ERROR - resulting in the process being terminated upon detection!
You can test this by executing the code in your terminal (-e
signifies "evaluate and run this code string"):
$ node -e "Promise.reject(); setTimeout(() => console.log('hello'), 1000)"
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "undefined".] {
code: 'ERR_UNHANDLED_REJECTION'
}
Node.js v18.12.1
You'll notice that 'hello'
never gets printed as the process terminates before one second elapses!
To confirm expected functionality, switch .reject
to .resolve
:
$ node -e "Promise.resolve(); setTimeout(() => console.log('hello'), 1000)"
hello
If you're developing a NodeJS application using any LTS supported version, it is crucial to handle errors to prevent unexpected crashes.
If your code exclusively runs on browsers, you might question the necessity of error handling - since users don't view the console, they remain unaware of issues. However, users desire feedback when something goes wrong with their application.
For instance, if your promise monitors the outcome of an API request submitting user-entered data, appropriate action should be taken if the API call fails to inform the user of the issue.
Failing to handle errors could result in perpetual loading spinners or misleading users into thinking their data was successfully submitted when it wasn't. Both scenarios lead to poor user experience!
Lastly, utilizing something like .catch(e => { throw e })
doesn't truly handle the error. While this may satisfy the linter, you're essentially generating a new rejected promise that will be logged to the console. Instead, integrate error handling into your application's UI, for example,
.catch(e => { alert(e); throw e })
would be more beneficial.