1
votes

I've started playing around with async/await in the latest version of node and I'm running into an issue when trying to await something within a catch.

Let's say I have the following function to check to see if a directory exists and create folders as necessary if not:

const Promise = require("bluebird");
const fs = Promise.promisifyAll(require("fs"));
const path = require("path");

async function ensureDirectoryExists(directory) {
    try {
        console.log("Checking if " + directory + " already exists");
        await fs.openAsync(directory, "r");
    } catch (error) {
        console.log("An error occurred checking if " + directory + " already exists (so it probably doesn't).");
        let parent = path.dirname(directory);

        if (parent !== directory) {
            await ensureDirectoryExists(parent);
        }

        console.log("Creating " + directory);
        await fs.mkdirAsync(directory);
    }
}

If I call it in the following manner (providing it a directory path in which none of the folders exist), I get the expected output ("Ensured that the directory exists." comes last).

async function doSomething(fullPath) {
    await ensureDirectoryExists(fullPath);
    console.log("Ensured that the directory exists.");
}

However, as I understand it, every async function returns a promise, so I figured the following would also work:

function doSomething2(fullPath) {
    ensureDirectoryExists(fullPath).then(console.log("Ensured that the directory exists."));
}

In this case though, the then is executed right after the first call to fs.openAsync even though there is an error produced and the rest of the code still executes as expected. Does ensureDirectoryExists not return a promise because it doesn't actually explicitly return anything? Is everything messed up because of the awaits within the catch and it only appears to work when called from doSomething?

1

1 Answers

0
votes

You're calling .then on your promise wrong; it expects a function that would call console.log:

ensureDirectoryExists(fullPath)
  .then(function() { // <-- note function here
    console.log("Ensured that the directory exists.");
  });

Or in short form, with arrow functions:

ensureDirectoryExists(fullPath)
  .then(() => console.log("Ensured that the directory exists."));

If you don't wrap it in a function like this, console.log(...) will be evaluated and run immediately (thus it may log before ensureDirectoryExists has completed). By giving in a function instead, the promise is able to call this function when the async function has completed.