What is the importance of always catching errors in a Promise?

In my project, I have implemented the

@typescript-eslint/no-floating-promises
rule. This rule highlights code like this -

functionReturningPromise()
    .then(retVal => doSomething(retVal));

The rule suggests adding a catch block for the Promise. While it makes sense to include logic in an exception handling block, sometimes I find myself not needing it. I am okay with letting the error be thrown. To avoid the error raised by this rule, I often end up doing the following -

functionReturningPromise()
    .then((retVal) => doSomething(retVal))
    .catch((error) => {
        throw error;
    });

Interestingly, even without the explicit catch block as shown above, the error still gets thrown (at least that's what I observe in my console output). So, I question the necessity of specifying the catch block. Am I overlooking something? Does adding/not adding the catch block affect how the error is thrown?

Answer №1

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.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Typescript is throwing an error stating that utilizing 'undefined' as an index type is invalid

When working with TypeScript and React, I pass xs, sm, md, lg as props to the component. Each size corresponds to a specific pixel value (14px, 16px, 18px, 24px) that is then passed to an Icon component. The errors mentioned in point (1) occur at the line ...

Error in Browserify Express App: Unexpected token while parsing the file

I have been attempting to browserify a javascript file. When I run the command: browserify global.js -o bundle.js An error message is returned: Error: Parsing file C:\ocquiz\public\javascripts\global.js: Unexpected token (756 ...

Ensuring the accurate usage of key-value pairs in a returned object through type-checking

After generating a type definition for possible response bodies, I am looking to create a function that returns objects shaped as { code, body }, which are validated against the typing provided. My current solution looks like this: type Codes<Bodies> ...

Having trouble getting the convert-multiple-files npm package to function properly on an Elastic Beanstalk environment running Amazon Linux

Following a successful deployment, I encountered an issue with my file conversion script when attempting to convert files as outlined in the documentation. The script works flawlessly on both a local Windows 10 machine and Ubuntu 20.04 LTS. const { conv ...

What is the best way to convert a recordset to an array using React?

I'm attempting to create an array by retrieving data from a SQL recordset: +------------+------------+------------+ | start_type | field_name | start_text | +------------+------------+------------+ | 0 | Field1 | some text. | +----------- ...

Encountered an issue while trying to establish a connection between node.js and MongoDB

db connection error querySrv ENOTFOUND _mongodb._tcp.nodeapi.vlvom.mongodb.net (node:7720) UnhandledPromiseRejectionWarning: Error: querySrv ENOTFOUND _mongodb._tcp.nodeapi.vlvom.mongodb.net at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) (Us ...

Should you opt for returning [something] or (nothing) in Javascript with ExpressJS?

Is there a distinct contrast between returning something and returning nothing? Let's take a look at an example: user.save(function(err){ if ( err && err.code !== 11000 ) { console.log(err); console.log(err.code); res.send(&apo ...

Is it possible to utilize a JavaScript framework within a Chrome extension?

Currently, I am developing a chrome extension that adds a toolbar to the DOM dynamically. In order to find, attach, and manipulate elements, I have been using CSS selectors in JavaScript. However, this approach has proven to be fragile as any changes made ...

The connection was refused by hapi.js

We have recently encountered an issue while using hapijs: hapi, {"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","domainEmitter":{"domain":{"domain":null,"_events":{},"_maxListeners":10,"members":[]},"_events":{},"_maxListeners":10},"doma ...

What methods can be used to modify the appearance of the cursor depending on its position?

Is there a way to change the cursor to a left arrow when on the left half of the screen and switch it to a right arrow when on the right half, using JavaScript? I am trying to achieve something similar to what is shown on this website. I attempted to acco ...

Create a lockscreen feature in AngularJS that becomes active after a period of inactivity

I am looking to integrate a lockscreen feature into my app using Angular.js. This lockscreen will consist of a route and an HTML template containing a form that prompts the user to re-enter their password in order to keep their session active. The purpose ...

Unable to run the command npm run env:restart

Currently, I am in the process of running a basic example. The initial setup involved configuring the convector workspace by installing convector-cli and hurley, as well as performing an npm installation. However, when attempting to execute npm run env:r ...

Using interpolation brackets in Angular2 for variables instead of dots

I'm curious if Angular2 has a feature similar to the bracket notation in Javascript that allows you to use variables to select an object property, or if there is another method to achieve the same functionality. Here is the code snippet for reference ...

Troubleshooting Cross-Origin Read Blocking with the Google Maps Elevation API using Axios in a Vue.js Application

I'm currently working on integrating the Google Maps API into a Vue.js project. I've encountered an issue with two Google Maps services: - The Time Zone API is functioning properly. - However, the Elevation API is giving me a Cross-Origin Read Bl ...

Adding over 20,000 rows to a table can be time-consuming, causing the page to become unresponsive once the process is complete

Looking at my table structure, it appears as follows: <tr ng-repeat="friend in friends | orderBy:predicate:reverse"> <td>{{friend.name}}</td> <td>{{friend.phone}}</td> <td>{{f ...

Execute a function upon mounting of an API endpoint

I have been working with an Express router in my application. I am trying to execute a function when a specific route is mounted. The setup involves two files, index.route.js and currentUser.route.js. index.route.js import currentUserRoutes from './ ...

Fluidly insert or delete elements

Is there a way to retrieve deleted elements from the DOM after using the jquery .remove function? I have a scenario where I am removing elements from the DOM, but now I'm wondering if it's possible to bring back those deleted elements without hav ...

Error: Value not defined in the (Node, Express, Pug, JQuery) environment

I'm encountering a common issue as a beginner and could really use some assistance. I have tried multiple solutions but still can't resolve the error "ReferenceError: $ is not defined" when attempting to use jQuery. My project structure looks lik ...

Currently, I am attempting to implement password strength validation using Angular

Looking for a way to implement password strength validation in Angular? You may encounter an error message like this: NullInjectorError: No provider for password strength! in the passwordstrength.ts file HTML <div class="validation_errors t ...

Develop a custom JavaScript code block in Selenium WebDriver using Java

Recently, I came across a JavaScript code snippet that I executed in the Chrome console to calculate the sum of values in a specific column of a web table: var iRow = document.getElementById("DataTable").rows.length var sum = 0 var column = 5 for (i=1; i& ...