Search code examples
javascriptnode.jsfirebasetry-catchfirebase-admin

Promise.catch() does not work with firebase-admin Node.js SDK


For example, auth.getUsers() only allows an array as arguments, so passing a string as shown below will result in an error, but the catch clause is not executed.

import { getAuth } from "firebase-admin/auth";

getAuth().getUsers("foo").catch(() => console.log("error"));

Why does this happen?

The above can be written in the following way in try-catch. In this case, the catch clause will be executed.

import { getAuth } from "firebase-admin/auth";

try {
  getAuth().getUsers("foo");
} catch {
  console.log("error");
}

Solution

  • The two code samples you're showing are not the same.

    In your first example, the catch method on a promise only captures errors that are specifically related to the resolution of that promise. It will not capture other language-related exceptions (such as programming mistakes, like the one you made). Those errors are called "thrown exceptions", which are different than rejected promises. If the function that returns the promise has some internal issue or crash not related to the resolution of the promise, the promise may never even get returned, or the returned promise may never get resolved (neither the then nor catch callbacks are invoked).

    In your second example, it's the exact opposite. The try/catch will actually never capture rejections of the promise returned by getUsers because it's not waiting for that promise to resolve. It will, however, capture general programming issues and crashes that would be caused by any of the synchronous code in the try block.

    Your second example will be more useful if you use async/await syntax, which is the only way that try/catch can be useful with promises using native JS syntax. When you use await, it will convert a rejected promise into a thrown exception so that it can be captured by the catch clause. Also you should consider assigning a variable for the generated exception so you can get more information about what went wrong.

    try {
      await getAuth().getUsers("foo");
    } catch(e) {
      console.log("error", e);
    }
    

    The above will capture both javascript-related programming errors, and also a rejection of the promise returned by getUsers. It's up to you to examine the e variable to determine which type of error it was, because it could be either. Of course, in order to use await, the code will have to itself be in an async function.

    Bottom line: The catch() callback for a promise is not the same as the catch handler in a try/catch (even though they have the same name).

    You may want to review some reference documentation: