Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Auth: Invalid email address crashing node.js (Express) app

I'm having a weird issue here. Simple code:

router.post("/resetpassword/:email", async (req, res) => {
    try {
        var auth = firebase.auth();
        await auth.sendPasswordResetEmail(req.params.email);
        res.sendStatus(200);
    } catch (e) {
        console.log(e);
        res.sendStatus(400);
    }
});

This code works fine if

  • The email is valid and known
  • The email is unknown (I get an exception with a status code that I can handle)

But if the email is malformatted, I also get an exception with status code, but then my Express application crashes after having invoked the catch block. The HTTP 400 is sent to the client, but after that, my app is dead.

Here's the console output. The first block if for an unknown email address, the second for a malformatted one.

{ [Error: There is no user record corresponding to this identifier. The user may have been deleted.]
  code: 'auth/user-not-found',
  message: 'There is no user record corresponding to this identifier. The user may have been deleted.' }



{ [Error: The email address is badly formatted.]
  code: 'auth/invalid-email',
  message: 'The email address is badly formatted.' }

[...]\node_modules\firebase\auth-node.js:39
h.send=function(a){if(a)if("string"==typeof a)this.sa.send(a);else throw Error("Only string data is supported");else this.sa.send()};h.abort=function(){this.sa.abort()};h.setRequestHeader=function(){};h.He=function(){this.status=200;this.responseText=this.sa.responseText;Ic(this,4)};h.Jd=function(){this.status=500;this.responseText="";Ic(this,4)};h.Je=function(){this.Jd()};h.Ie=function(){this.status=200;Ic(this,1)};var Ic=function(a,b){a.readyState=b;if(a.onreadystatechange)a.onreadystatechange()};var Jc=function(a,b,c){this.Ue=c;this.we=a;this.kf=b;this.oc=0;this.gc=null};Jc.prototype.get=function(){var a;0<this.oc?(this.oc--,a=this.gc,this.gc=a.next,a.next=null):a=this.we();return a};Jc.prototype.put=function(a){this.kf(a);this.oc<this.Ue&&(this.oc++,a.next=this.gc,this.gc=a)};var Kc=function(a){l.setTimeout(function(){throw a;},0)},Lc,Mc=function(){var a=l.MessageChannel;"undefined"===typeof a&&"undefined"!==ty
Error: The email address is badly formatted.
[nodemon] app crashed - waiting for file changes before starting...

I currently assume this is a stupid mistake from my side (I'm fairly new to node/Express). Any idea what I am missing here?

like image 730
Philipp Sumi Avatar asked Apr 04 '17 17:04

Philipp Sumi


1 Answers

I came across this error myself while working with firebase.auth() myself, and is very peculiar indeed. What I figured is that firebase.auth() seems to use it's own Promise variant, and it is going to crash your app if that promise does not catch the error, or even throw the error in the .then/.catch chained to it.

here is a small function I made that makes sure it turns the rejected promise into a resolved promise, before again turning it into a rejected promise. This prevented my app from crashing, but I couldn't find an easier way.

let firebase_auth_wrap = async (promise) => {
  let rejected = Symbol();
  let value_or_error = await promise.catch((error) => {
    return { [rejected]: true, error: error };
  });

  if (value_or_error[rejected]) {
    throw value_or_error.error;
  } else {
    return value_or_error;
  }
}

...

let { uid } = await firebase_auth_wrap(firebase.auth().signInWithEmailAndPassword(email, password));

Hope it works for you too, and let me know if it could be done more intuitively :)

like image 184
Michiel Dral Avatar answered Sep 20 '22 09:09

Michiel Dral