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

Is it possible to utilize a partial entity for saving with TypeORM?

My current table structure looks like this: --changeset 0004-order:ccushing create table if not exists "order"."order" ( id uuid primary key not null default uuid_generate_v4(), state uuid re ...

Unlocking the potential of input values in Angular.jsDiscovering the secret to

I'm currently experimenting with the angular date picker directive. My goal is to retrieve the entered date value from the date picker and log it to the console. However, all of my attempts so far have been unsuccessful. Here's a snippet of my c ...

Which five key JavaScript concepts should I grasp in order to excel as an AngularJS developer?

Coming from a background of server-side coding, I am delving into the world of AngularJS now. This means I need to have a solid grasp of JavaScript before diving in. If I don't have enough time to master JavaScript completely at the moment, what are ...

The feature for sending posts in Angular.js appears to be malfunctioning

I have developed a rest-API for adding todos in a MongoDB database. When I use Postman with the setup below, I can successfully save instances: http://localhost:3000/api/addtodo x-www-form-urlencoded with values text="Test", completed: "false". However, ...

In JavaScript, navigate to a new page only after successfully transmitting data to the server

Creating a redirect page that sends data to the server before transitioning to a new page can be achieved using JavaScript as shown below. <body> <script type="text/javascript"> **** Discussion of cookie-related transactions **** document.c ...

Creating Child Components in Vue Using Typescript

After using Vue for some time, I decided to transition to implementing Typescript. However, I've encountered an issue where accessing the child's methods through the parent's refs is causing problems. Parent Code: <template> <re ...

The issue of req.files being undefined in Express.js

I am aiming to upload files to s3 without depending on any middleware like multer. Below is the code snippet of my approach: <form role="form" action="/send" method="post"> <input type="file" name="photo" class="form-control"/> <button ...

AngularJS encountered an error following a successful GET request

I'm attempting to retrieve data from the server using this code snippet. $scope.get_file_list = function() { delete $http.defaults.headers.common['X-Requested-With']; //We don't want OPTIONS but GET request $htt ...

"Enhancing User Experience with Multiple Conditional Checkboxes in jQuery

Having difficulty making a checkbox change some HTML content using JQuery. There is a standard html checkbox with the following attributes <input type="checkbox" name="AQN1" class="checkbox Q1" value="AQN10" id="3mcq"> <input type="checkbox" nam ...

Display a specific division depending on the outcome of an Ajax request within a PHP form

My PHP form has a layout similar to this: <form> <div id="inid"> National ID: <input type="text" id="individual_nid" oninput="getIndividualName(this.value)" /> </div> <hr /> name: <div id="individua ...

Encountering a 500 server error while attempting to retrieve content from Google Images through the Web Speech API

My current project involves utilizing the Web Speech API to dynamically gather free images from Google. Here's how it works: I extract the search keyword using the Web Speech API in JavaScript. The keyword is then sent to the server (PHP) via an a ...

What factors contribute to TypeScript having varying generic function inference behaviors between arrow functions and regular functions?

Consider the TypeScript example below: function test<T = unknown>(options: { a: (c: T) => void, b: () => T }) {} test({ a: (c) => { c }, // c is number b: () => 123 }) test({ b: () => 123, a: (c) => { retur ...

What steps are needed to switch colors after a loop has been clicked?

I have a loop setup like this: data: { show: false } .test { hight: 10px; background-color: red; } .test2 { hight: 15px; } <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div v-for="value in da ...

Quick tip on closing an Angular-ui modal from a separate controller

I am currently using Angular-ui to display a modal with a form inside. Here is the code snippet: app.controller('NewCaseModalCtrl', ['$http', '$scope','$modal', function ($http, $scope, $modal, $log) { $scope.ite ...

Use Vue.js to display a class when the input is invalid and not empty

How can I apply a has-error class when an input is invalid and not empty in vue.js? <div class="form-group"> <input type="email" id="loginEmail" name="loginEmail" v-model="loginEmail" required> <label for="loginEmail">Email</label ...

Tips on utilizing index and eliminating React Warning: Ensure every child within a list has a distinct "key" prop

Hello, I am encountering an issue where I need to properly pass the index in this component. Can you help me figure out how to do that? Error: react-jsx-dev-runtime.development.js:117 Warning: Each child in a list should have a unique "key" prop ...

Customizing CSS based on URL or parent-child relationship in WordPress

I'm having trouble finding a solution for what seems like a simple issue... Currently, my header has a border-bottom and I'd like to change the color of this border based on the section the user is in. For example, consider these parent pages: ...

`Jump-start Your Development with jQuery Lightbox Centering`

Recently, I implemented a lightbox effect for images on my website. However, I encountered an issue where the lightbox was not centering properly in the window upon initial click. Instead, the lightbox would appear at the bottom of the page on the first cl ...

Exploring the world of JSON and JavaScript data structures

Can someone provide some clarification please? var a = '{"item":"earth", "color":"blue", "weight":920}'; Is the data type of a a string or an array ? var b = JSON.parse(a); What is the data type of b - an object or an array ? ...

"Enhancing User Experience with AngularJS by Dynamically Modifying and Refresh

I'm currently attempting to dynamically add HTML elements using JavaScript with a directive: document.getElementsByClassName("day-grid")[0].innerHTML = "<div ng-uc-day-event></div>"; or var ele = document.createElement("div"); ele.setAttr ...