Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

526
Views
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?

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

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 :)

about 4 years ago · Santiago Trujillo Report

0

When you run this:

await auth.sendPasswordResetEmail(req.params.email);

inside of a try/catch block then you handle two things:

  1. The auth.sendPasswordResetEmail() throwing an exception immediately
  2. The auth.sendPasswordResetEmail() rejecting the returned promise

What you don't handle is when in some other part of your code something happens and thrown an exception that is not caught by anything.

Of course it's impossible to tell you where it happened in your case when you post an example of an error message pointing to a line with thousands of characters but here is a simple example.

In this example you will catch the rejected promise:

let f = () => new Promise((res, rej) => {
  rej(new Error('Error'));
});
(async () => {
  try {
    let x = await f();
    console.log('Returned value:', x);
  } catch (e) {
    console.log('Handled error:', e.message);
  }
})();

In this example you will catch the thrown exception:

let f = () => new Promise((res, rej) => {
  throw new Error('Error');
});
(async () => {
  try {
    let x = await f();
    console.log('Returned value:', x);
  } catch (e) {
    console.log('Handled error:', e.message);
  }
})();

In this example you will handle the rejection that happened in a different tick of the event loop:

let f = () => new Promise((res, rej) => {
  setImmediate(() => rej(new Error('Error')));
});
(async () => {
  try {
    let x = await f();
    console.log('Returned value:', x);
  } catch (e) {
    console.log('Handled error:', e.message);
  }
})();

But in this example you will not handle the exception thrown on a different tick of the event loop:

let f = () => new Promise((res, rej) => {
  setImmediate(() => { throw new Error('Error'); });
});
(async () => {
  try {
    let x = await f();
    console.log('Returned value:', x);
  } catch (e) {
    console.log('Handled error:', e.message);
  }
})();

Something like that must be happening in your case.

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!