1

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.

Mike
  • 14,010
  • 29
  • 101
  • 161
  • how come you are awaiting `res.json`? – Rezaa91 Oct 08 '20 at 20:21
  • 1
    you wouldn't await on the server response. You are maybe getting mixed up with `fetch` json response, which you would `await` – Rezaa91 Oct 08 '20 at 20:26
  • @Rezaa91, I've investigated the case and adjusted the question according to my findings. – Mike Oct 10 '20 at 14:28
  • 1
    _handleFileOperationException in your catch handler has no handler if it results in an exception, if it's actually something `await`able. Is it possible that's where the actual unhandled exception is coming from? – Joe Oct 10 '20 at 14:35
  • @Joe, I've completely removed `_handleFileOperationException` but the problem still persists. I've simplified the code snippet. – Mike Oct 10 '20 at 14:40

2 Answers2

1

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.

Mike
  • 14,010
  • 29
  • 101
  • 161
0

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);
  }
}
Mike
  • 14,010
  • 29
  • 101
  • 161
Rezaa91
  • 500
  • 2
  • 10
  • I've rollbacked a code snippet to my initial code version, which is actually very similar to your. But still the problem persists. – Mike Oct 08 '20 at 20:46
  • Cheers, and is that try...catch wrapped in an async function too? – Rezaa91 Oct 08 '20 at 20:49