To get a download link to the file hosted on Dropbox, I'm using a Dropbox JavaScript API (7.0.0):

export const fileDownload = async function fileDownload(fileUUID) {

    let isSucceeded;
    let message;
    let file;
    const dbx = _dropboxFactory();

    try {
        const operationResult = await dbx.filesGetTemporaryLink({
            path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`
        });

        if ("OK" === http.STATUS_CODES[operationResult.status].toUpperCase()) {

            file = Object.freeze({
                length: operationResult?.result?.metadata?.size,
                link: operationResult?.result?.link,
                mime: mime.lookup(operationResult?.result?.metadata?.name),
                name: operationResult?.result?.metadata?.name
            });
            isSucceeded = true;
            message = SYS_MESSAGES.storageFileDownloadSucceeded.code;

        } else {
            isSucceeded = false;
            message = SYS_MESSAGES.storageFileDownloadFailed.code;
        }
    } catch (err) {
        file = "error";
        isSucceeded = false;
        message = "FIL_NOT_FOUND";
    }

    const downloadResult = Object.freeze({
        file,
        isSucceeded,
        message
    });

    return downloadResult;

};

The problem is that when the path to the file is wrong, I get a Node.js exception:

(node:9156) UnhandledPromiseRejectionWarning: #<Object>

(node:9156) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)

(node:9156) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I've tested several options and came to conclusion that the issue is in:

const operationResult = await dbx.filesGetTemporaryLink({
    path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`
});

My questions:

  1. Why does Node.js claim «unhandled promise rejection» or «promise which was not handled with .catch()» and throws an UnhandledPromiseRejectionWarning exception if the code, which generates it is wrapped by try-catch?

  2. Starting Node.js 15.x.x, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. Therefore, how to avoid UnhandledPromiseRejectionWarning?

A temporal workaround:

To run Node.js with a flag --unhandled-rejections=warn.
This will prevent the termination of the Node.js process with a non-zero exit code upon UnhandledPromiseRejectionWarning.

2

There are 2 best solutions below

0
On BEST ANSWER

The problem was in the Dropbox library and has been solved by the Dropbox team with the release of 7.1.0. After upgrading the code in the question works correctly.

2
On

try changing your fileResponse function to something like this. You are mixing up async/await with .then().catch() style syntax.

Just wrap your function in a try-catch

async function getDocument() {
  try {
    const response = await fetch(`${http() + ip}/downloadDocument`, {
      body: JSON.stringify({fileUUID: oModel.oData[0].documentFile}),
      cache: "no-cache",
      credentials: "same-origin",
      headers: {
        "Content-Type": "application/json"
      },
      method: "POST",
      mode: "cors"
    });

    const data = await response.json();
    
    return data;
  } catch(err) {
    console.log(err);
  }
}