Detecting errors in asynchronous functions within other asynchronous functions

I'm attempting to capture errors in nested asynchronous functions to perform a rollback if an error occurs.

Initially, I have a try-catch block where I call a function that then calls another function. The final function should throw an error, and I anticipated that the initial try block would catch this error. However, it does not. Here is my code:

The function with the initial try/catch block:

exports.add = (req, res) => {
    const { product, type } = req.body

    try {
        switch (type) {
            case ProductsTypes.TRACK:
                addTrack(product, req.files)
                res.status(200).json({ message: 'SUCCESS !' })
                break
            default:
                res.status(400).json({ message: 'INVALID TYPE !' })
        }
    } catch (error) {
        // ROLLBACK HERE
        res.status(400).json({ message: "Error Exception, Need to rollback", error })
    }
}

The function where I expected to catch the error to send it back:

const addTrack = (product, files) => {
    const imageFile = files[NamesAddTrackForm.TRACK_IMAGE][0]
    const audioFile = files[NamesAddTrackForm.TRACK_AUDIO][0]
    const stemsZip = files[NamesAddTrackForm.TRACK_STEMS][0]

    FilesFormatter.resizeImage(imageFile, 500, 500) // It was assumed that this function would throw an exception
}

The function where I intentionally throw the error:

resizeImage = (file, width, height) => {
    try {
        sharp(file.path)
            .resize(width, height)
            .jpeg({ quality: 90 })
            .toBuffer((err, buffer) => {
                fs.writeFileSync(file.path, buffe, (err) => { // Here, I purposely introduced an error by misspelling buffer as buffe
                    if (!err) {
                        throw Error(err)
                    }
                })
            })
    } catch (error) {
        throw Error(error)
    }
}

I am seeking guidance on how to effectively manage these types of errors to relay them back to the primary one. This approach will help me implement similar logic in other files for rolling back actions like database insertions or file creations in case of errors during code execution, preventing illogical data accumulation.

Answer №1

In order to handle errors from an asynchronous operation, it is necessary for the resizeImage function to return a Promise.

Furthermore, the function should be marked with the async keyword to allow the usage of await.

You can attempt the following approach: (Code not tested.)

const fs = require("fs").promises;

class FilesFormater {
    static resizeImage = async (file, width, height) => {
        try {
            const { data } = await sharp(file.path)
                .resize(width, height)
                .jpeg({ quality: 90 })
                .toBuffer();

            await fs.writeFile(file.path, data);
        } catch (error) {
            throw new Error(error);
        }
    };
}

const addTrack = (product, files) => {
    const imageFile = files[NamesAddTrackForm.TRACK_IMAGE][0];
    const audioFile = files[NamesAddTrackForm.TRACK_AUDIO][0];
    const stemsZip = files[NamesAddTrackForm.TRACK_STEMS][0];

    return FilesFormater.resizeImage(imageFile, 500, 500); // a Promise is returned.
};

exports.add = async (req, res) => {
    const { product, type } = req.body;

    try {
        switch (type) {
            case ProductsTypes.TRACK:
                await addTrack(product, req.files); // wait for the Promise
                res.status(200).json({ message: "SUCCESS !" });
                break;
            default:
                res.status(400).json({ message: "INVALID TYPE !" });
        }
    } catch (error) {
        // ROLLBACK HERE
        res.status(400).json({
            message: "Error Exception, Need to rollback",
            error,
        });
    }
};

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

The onclick function fails to function properly following an Ajax reload of the <div> element

I have an issue with my onclick function that only works the first time. Every time the onclick function triggers an ajax request, it successfully reloads a div which contains code to retrieve values from SQL and build an HTML table using a for loop. Alth ...

Function in head not triggering on OnMouseOver event

My goal is to have specific text display on my page when a user hovers over an image, with the text changing for each image. Below is the code snippet for the header section: <head> <title>Indian Spices Page</title> <link rel="s ...

Retrieve JSON data by making a POST request to a website's API

Can you help me retrieve Json data from a website API using JavaScript? I'm trying to fetch quotes from the following website: for my quotes generator page. While I have some understanding of making GET requests, it seems that this API requires POST ...

What is the best method for storing a third-party image in cache?

Running my website, I aim to achieve top-notch performance scores using LightHouse. I have successfully cached all the images I created (Cache-Control: public, max-age=31536000). Unfortunately, third-party website images are not cached. How can I cache t ...

Monitoring individual elements of an array within an Angular service

Is there a way to monitor changes in an array element within a service? Let's consider the following scenario with CartController and ProductListService. Within the ProductListService, data is fetched as follows: /** * Fetch all the products in us ...

What is the best way to deselect all "md-checkboxes" (not actual checkboxes) on an HTML page using a Greasemonkey script?

After spending a frustrating amount of time trying to disable the annoying "md-checkboxes" on a certain food store website, despite unchecking them multiple times and reporting the issue without any luck, I have come to seek assistance from knowledgeable e ...

Implementing a color change for icons in React upon onClick event

export default function Post({post}) { const [like,setLike] = useState(post.like) const [islike,setIslike] = useState(false) const handler=()=>{ setLike(islike? like-1:like+1 ) setIslike(!islike) } return ( <> <div classNam ...

Remove the class upon clicking

I recently created a toggle-menu for my website that includes some cool effects on the hamburger menu icon. The issue I am facing is that I added a JavaScript function to add a "close" class when clicking on the menu icon, transforming it into an "X". Whil ...

Unable to load files in Handlebars when using Node and Express

Currently, I am in the process of developing a Node/Express web application for basic CRUD operations. However, I am encountering difficulties incorporating Handlebars into my project. Whenever I attempt to utilize Handlebars, none of the stylesheets from ...

Exploring the transparency of material lab autocomplete drop-down text for enabling multiple selections

Check out this demo for checkboxes and tags in Material UI The code below demonstrates an autocomplete component that functions correctly. However, the drop-down text appears transparent. Is there a way to fix this issue without modifying any libraries? ...

Issue encountered when trying to use Node module in Electron application

I am currently in the process of developing an application that makes use of the node-bluetooth module from npm. However, I have encountered the following error: App threw an error during load Error: The module '/home/pi/AlucentOs/node_modules/node- ...

Difficulty encountered while attempting to deploy the front-end on Heroku

I recently completed a typeorm project with the following structure: https://i.stack.imgur.com/ReQK1.png Both the client and root directories contain index files located in the src directory. In the package.json file within the client directory, I made a ...

Use jQuery to switch back and forth between two different sets of classes

I am attempting to switch between two different sets of classes using jQuery. My goal is to change from one custom icon to a font-awesome icon upon clicking an element. While I have been successful in changing a single class, I am facing challenges when tr ...

A guide on using jCrop to resize images to maintain aspect ratio

Utilizing Jcrop to resize an image with a 1:1 aspect ratio has been mostly successful, but I've encountered issues when the image is wider. In these cases, I'm unable to select the entire image. How can I ensure that I am able to select the whole ...

Tips for implementing and utilizing onclick functions in EJS

My goal is to develop a trivia game with interactive features. I aim to enable users to click on an answer, which will trigger a border effect and increase the points variable. Below is the layout of the entire page: <% include ../partials/boilerp ...

Displaying a message text upon successful AJAX request

I have a web page with an AJAX request that updates data in the database. After the update, I want to display a message to the user on the webpage confirming that the data has been successfully updated. However, currently, no message is being displayed and ...

Are there any similar tools to Graphstream in Java that can be used with HTML5 using canvas and JavaScript?

GraphStream is a revolutionary graph library created in Java that offers Java developers a simple way to visually represent dynamic graphs either in memory, on screen, or in files. Check out this demo video. With GraphStream, you can effectively handle th ...

Learn how to manage Ajax GET/POST requests using nodejs, expressjs, and Jade Template Engine

I am currently working on a project that involves the use of NODE, EXPRESS, and JADE TEMPLATE ENGINE, as well as AJAX to optimize page loading. However, I encountered an issue when trying to utilize the data received from a GET request in AJAX directly wit ...

Content Security Policy Error triggered by Iframe Source Running Script in Web Extension

My web extension for Firefox utilizes a content script to add HTML to a webpage when a button is clicked. The injected HTML includes an iFrame nested in multiple div elements. Below is the relevant part of the content script: var iFrame = document.create ...

The Bootstrap carousel controls now add the carousel ID to the address bar instead of just moving to the next slide

I can't figure out why my carousel isn't working. The id of the carousel is showing up in the webpage's address, which usually happens when the 'bootstrap.js' file is missing, but I have included it. Can anyone help me troubleshoo ...