Home > other >  Exception could not catch from calllbacked function
Exception could not catch from calllbacked function

Time:05-16

I am calling a login function using firebase authentication and checking the custom user claim. If not, then throw the exception. I could not catch the exception in caller function. May I know why?

const handleLogin = async (data) => {
console.log(data);
setIsSubmitting(true);
auth
  .login(data.email, data.password)
  .then((res) => {
    navigate(from, { replace: true });
  })
  .catch((error) => {
    console.log(error.message);
    const message = auth.mapAuthCodeToMessage(error.code);
    setLoginError(message ?? error.message);
  })
  .finally(() => {
    mounted.current && setIsSubmitting(false);
  });
};

firebase authentication

async function login(email, password) {
return signInWithEmailAndPassword(auth, email, password).then(
  async function (res) {
    const currentUser = getAuth().currentUser;
    if (currentUser) {
      currentUser.getIdTokenResult().then(async function (idTokenResult) {
        if (idTokenResult.claims.role == "ADMIN") {
          await signIn(idTokenResult.token);
        } else {
          throw new Error("You role is not authorised!");
        }
      });
    }
  }
);
}

CodePudding user response:

Because you're not returning the promise here:

async function login(email, password) {
return signInWithEmailAndPassword(auth, email, password).then(
  async function (res) {
    const currentUser = getAuth().currentUser;
    if (currentUser) {
      currentUser.getIdTokenResult().then(async function (idTokenResult) { // ***
        if (idTokenResult.claims.role == "ADMIN") {                        // ***
          await signIn(idTokenResult.token);                               // ***
        } else {                                                           // ***
          throw new Error("You role is not authorised!");                  // ***
        }                                                                  // ***
      });                                                                  // ***
    }
  }
);
}

You need to return that promise for the caller to know about the rejection.

But there's a more fundamental issue: You're not making any use of the fact you're using async functions. There's no point to an async function that doesn't have any await in it. In general, don't mix async functions with explicit promise callbacks, it's much too easy to make mistakes like not returning the promise. Instead, use await.

Here's a translation of those functions using await (note: it may not be perfect, it's meant to guide you in the right direction, but naturally I can't run it nor do I know your context, so adjust as necessary):

const handleLogin = async (data) => {
    console.log(data);
    setIsSubmitting(true);
    try {
        await auth.login(data.email, data.password);
        navigate(from, { replace: true });
    } catch (error) {
        console.log(error.message);
        const message = auth.mapAuthCodeToMessage(error.code);
        setLoginError(message ?? error.message);
    } finally {
        if (mounted.current) {
            setIsSubmitting(false);
        }
    }
};

async function login(email, password) {
    const res = await signInWithEmailAndPassword(auth, email, password);
    const currentUser = getAuth().currentUser;
    if (currentUser) {
        const idTokenResult = await currentUser.getIdTokenResult();
        if (idTokenResult.claims.role == "ADMIN") {
            await signIn(idTokenResult.token);
        } else {
            throw new Error("You role is not authorised!");
        }
    }
};
  • Related