Guide to encapsulating JavaScript fetch within a function - dealing with unhandled promise rejection

I'm attempting to create a wrapper function for JavaScript's fetch command.

I found the following example code on this post:

function fetchAPI(url, data, method = 'POST') {
const headers = {
    'Authorization': `Token ${getAuthToken()}`,
};

return fetch(url, { headers, 'method': method, 'body': data })
    .then(response => {
        if (response.ok) {
            const contentType = response.headers.get('Content-Type') || '';

            if (contentType.includes('application/json')) {
                return response.json().catch(error => {
                    return Promise.reject(new Error('Invalid JSON: ' + error.message));
                });
            }

            if (contentType.includes('text/html')) {
                return response.text().then(html => {
                    return {
                        'page_type': 'generic',
                        'html': html
                    };
                }).catch(error => {
                    return Promise.reject(new Error('HTML error: ' + error.message));
                });
            }

            return Promise.reject(new Error('Invalid content type: ' + contentType));
        }

        if (response.status === 404) {
            return Promise.reject(new Error('Page not found: ' + url));
        }

        return response.json().then(res => {
            let errors = [];
            Object.keys(res).forEach((key) => {
                errors.push(`${key}: ${res[key]}`);
            });
            return Promise.reject(new Error(errors)
            );
        });
    }).catch(error => {
        return Promise.reject(new Error(error.message));
    });

};

Here is how I am using it:

fetchAPI('/api/v1/rest-auth/password/change/', formData).then(response => {
        console.log('response ', response);
    });

Edit: I have made adjustments to show server information in case of a rejected request due to reasons like an incorrect password. You need to check the response JSON if ok == false.

A successful URL fetch works as expected. However, when there is an error, I encounter an Unhandled Rejection (Error): error message.

Why are these rejections considered unhandled even though they are caught in catch blocks? What's the explanation here?

Answer №1

To prevent an unhandled promise rejection, you must always handle it:

fetchAPI('/api/v1/rest-auth/password/change/', formData).then(response => {
    console.log('response ', response);
}).catch(error => {
   // take appropriate action here.
});;

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 there still a need to preload dynamic images in the background?

Imagine you have HTML code that includes an image with a placeholder: <img class="lazy-load" src="http://via.placeholder.com/150/?text=placeholder" data-src="http://via.placeholder.com/150/?text=real%20image"/> At some stage, you want to implem ...

Using environmental variables in Nuxt 2 or Nuxt 3 - a step-by-step guide

I have an .env file located in the root of my project. In my nuxt config, I am using variables to configure ReCaptcha as shown below: import dotenv from 'dotenv' dotenv.config() export default { modules: [ ['@nuxtjs/recaptcha&ap ...

Incorporating TextBox Values into a List Using Bootstrap

Currently, I am in the process of developing an application using C# ASP.NET MVC 5 with Bootstrap and jQuery. My familiarity with JavaScript is limited at this time. 1. Initially, my question was how to modify the JavaScript to restrict input to a specifi ...

vue-router default route for children

Currently, I am working on a Vue 2.x application and utilizing vue-router for routing purposes. In certain situations, I need to directly display a child vue. The template structure is as follows: | voice 1 | voice 2 | voice 3 | | submenu 1 | submen ...

What is the best way to locate and access a JSON file that is relative to the module I am currently working

I am in the process of creating a package named PackageA, which includes a function called parseJson. This function is designed to accept a file path pointing to a JSON file that needs to be parsed. Now, in another package - PackageB, I would like to invok ...

Having trouble establishing a connection to MySQL through NodeJS and Express

I am currently attempting to establish a connection to MySQL using a nodeJS app with express as the server. I have referred to the mysql npm documentation to start the connection process, but I keep encountering an error in the callback function within cre ...

Invoke a specific script snippet by its identifier within a React single-page application, causing the content to appear only upon manual

I am currently working on a React application that utilizes a third-party JS script from OneTrust cookie scripts. Unfortunately, the scripts provided are not optimized for single-page applications (SPAs). At the moment, I am simply referencing the script s ...

The final piece left in stitching together an array

Issue I have been struggling with this code for some time now and I can't seem to figure out the solution. I am receiving 3 values from inputs and trying to remove all the empty spaces "" in the array, but when I execute the code, it displays the foll ...

Executing a JavaScript function when a column in a Fusion Chart is clicked

I have two div elements in HTML and I would like to have div2 load when div1 is clicked. Additionally, whenever div2 loads, a back button should also appear to return to div1. Is there a way to achieve this using HTML? <td background="images/bgTd.gif ...

Access denied, can forever.js be used as a bash script?

After some troubleshooting, I managed to set up a bash script that allows me to run indefinitely. In FileZilla, I went ahead and modified the permissions for /usr/local/lib/node_modules/forever to 777. post-receive bash script #!/bin/sh git --work-tree=/ ...

Webpack failing to load jQuery correctly

In the process of transitioning my application.js application into smaller page bundles using SplitChunks, I have encountered a situation in my users/show.html.erb page where I am utilizing the following tag to import the specific chunk. <%= javascript ...

Managing Input Type Dropdown Selections Using Jquery

I am currently in the process of developing a website. On this website, there is a form that includes 3 dropdown menus as shown below. I would like to implement a feature where selecting the number 5 from the Adults menu will automatically display 5 in the ...

Use JQuery to gradually decrease the opacity of divs individually

I am currently working on a function that fades out all divs except the one that has been clicked on simultaneously. However, I want them to fade out one by one instead. Additionally, I would like the divs to fade out in a random order. If anyone knows ho ...

Encountering a "Start script missing" error while trying to execute npm start, the problem remains even after attempting

Help, I keep encountering this issue npm ERR! missing script: start whenever I attempt to execute 'npm start' for my latest React project. I've tried searching for a solution and came across some individuals who were able to resolve it by u ...

Is there a way to receive a JSON request in Express delete using Restangular?

Below is the Restangular code that I am using for deleting an object: $scope.delO = (id){ Restangular .one("footer", id) .get() .then((ob) => { ob.remove(); } .catch.... } The deletion request is being successfully sent, co ...

Issue: RangeError [ERR_BUFFER_OUT_OF_BOUNDS] Encountered while Retrieving Data from Firestore Database

I am facing an issue when attempting to retrieve a user profile document from Firestore using Node.js. Here is a snippet of my code: const profileRef = db.collection("profiles").doc(uid); const profileSnapshot = await profileRef.get(); if (!prof ...

showcasing a set of div elements by using forward and backward buttons

I am dealing with 5 divs that have text content inside. To navigate through each div, I have implemented a back and next button system. <a href="" class="back-btn off">Back</a> | <a href="" class="next-btn">Next</a> <div class ...

What is the best way to present these values with spaces in between each word?

When I use console.log(JSON.stringify(selected["1"]?.others)), the output is: ["Cars","Books","Necklaces"] On the screen, however, when displaying this data, all the words appear together without spaces. It looks li ...

Having an issue with Vue Router in Vue 2.0, encountering an error

I encountered the following error message: [Vue warn]: Unknown custom element: <router-view> - did you register the component correctly? For recursive components, make sure to provide the "name" option. I double-checked that the Vue router ...

Adjust the Height of a Pair of Floating DIVs on the Fly

I have completed the coding using Visual Studio 2008. On my webpage, I have two div sections named "dvLeftContent" and "dvRightContent". The issue I am facing is that I cannot set a static height for these divs because the height of "dvRightContent" vari ...