简体   繁体   中英

Unhandled Rejection outside Promise?

So basically I am running some code that queries a graphql api, and checks whether the data field inside is null (meaning there are no hits for the query), like so:

    // check if the items have available data.
    // if not, throw an error message saying which ones did not have data.
    const testIfDataInDB = await Promise.all(objIDs.map(objID => {
        return fetch("/api/graphql", {
            method: "POST",
            headers: headers,
            body: JSON.stringify({
                query: "query get_object_with_obj_number($objectNumber: String!) { constructionDetail(objectNumber: $objectNumber) { objectNumber } }",
                variables: {
                    objectNumber: objID
                }
            }
            )
        }).then(async (res) => {
            return {
                responseData: await res.json(),
                objID: objID
            }
        }
        )
    }));
    const itemsDataNotFound = testIfDataInDB.filter(o => 
      o.responseData?.data?.constructionDetail === null);
    let errString = "";
    if (itemsDataNotFound.length > 0) {
        itemsDataNotFound.forEach(obj => {
            errString = errString + `${obj.objID}, `;
        });
        errString = errString.slice(0, errString.length - 2);
        console.log(errString);
        throw new Error(errString);
    }

   // ... do some object transformations ...   

   // proceed to post some items into another db using fetch.
   const response = await Promise.all(objectsArr.map((obj, index) => {

        const body = JSON.stringify(obj);
        if (update && index === 0) {
            const fetchUrl = `${baseFetchUrl}/${parentItemMetadata._id}`
            return fetch(
                fetchUrl, {
                method: "PUT",
                headers: headers,
                body: body
            }
            ).then(res => res.json())
        }
        return fetch(
            baseFetchUrl, {
            method: "POST",
            headers: headers,
            body: body
        }
        ).then(res => res.json())
    }))

    console.log(response);
    return response;
}

full code for this part

and the way im calling this code inside my react component:

//defined in parent
const saveMultipleItems = async (
    objIDs: string[],
    update: boolean
  ) => {
    const parentItemMetaData: TypeLabelItemMetaData = {
      createdBy: currentItem?.createdBy || "",
      createdAt: currentItem?.createdAt || "",
      updatedBy: currentItem?.updatedBy || "",
      updatedAt: currentItem?.updatedAt || "",
      _id: currentItem?._id || "",
      collection: currentItem?.collection || ""
    }
    try {
      saveMultiple(
        objIDs,
        labelType,
        values as TypeLabelState,
        parentItemMetaData,
        user,
        update
      )
    } catch (e) {
      console.warn(e.message);
    } finally {
      fetchItems();
    }


// called in child component
onSubmit={(e) => {
    e.preventDefault();
    console.log("submitting a series")
    try {
       const pNumbersArray = generateArray(fromObjNumber, toObjNumber);
       saveSeriesFn(pNumbersArray, editMode);
       } catch (e) {
         console.log("catched error")
         alert("Saving series failed with message " + e.message);
    }
  }
}

My plan was to throw an error, and react to this error somewhere where I can show an alert saying that some items are not available to be saved, and abort the saving operation. I kn I know this may not be the cleanest way to do this (I am also very grateful for sugestions). The problem I am having right now, is that the app crashes with the following:

Unhandled Rejection (Error): P18100405117, P18100405118, P18100405119
saveMultiple
src/app/src/api/savemultiple.ts:70
  67 |     });
  68 |     errString = errString.slice(0, errString.length - 2);
  69 |     console.log(errString);
  70 |     throw new Error(errString);
     | ^  71 | }
  72 | 
  73 | const objectsArr: SaveTemplateObjType[] = objIDs.map((objID, index) => {

I thought I was not inside a Promise at the moment I threw this Error?

Async/Await is a synthetic sugar for Promises

Your code states: const saveMultiple = async(...

An Async function will always return a Promise. (see refs below)

Your try/catch doesnt take affect in:

 try {
      saveMultiple(
        objIDs,
        labelType,
        values as TypeLabelState,
        parentItemMetaData,
        user,
        update
      )
    } catch (e) {
      console.warn(e.message);
    } finally {
      fetchItems();
    }

because saveMultiple is async. you need to use:

    saveMultiple(
        objIDs,
        labelType,
        values as TypeLabelState,
        parentItemMetaData,
        user,
        update
      ).catch((e) => {
      console.warn(e.message);
    }).finally(() => {
      fetchItems();
    })

From MDN : 异步函数API

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM