Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can I interrupt Javascript by throwing an exception in a Promise? UnhandledPromiseRejectionWarning

I have a simple Web app running with NodeJS and Express. It has a route where an outside 3rd party can POST us a XML document, which we then convert to JSON then save to our MongoDB database. A few things can go wrong:

The XML can be malformed

The request might be empty

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The outside 3rd party might send us duplicate documents

Rather than having an endless series of then() blocks, going deeper and deeper, indented further and further, I wanted to throw an exception for each possible error, and then catch those errors at the top level and process them there.

So we find a unique id and then check to see if this unique id is already in MongoDB:

// will throw an error if there is a duplicate
document_is_redundant(AMS_945, unique_id);

The function looks like this:

function document_is_redundant(this_model, this_unique_id) {

return this_model.findOne({ unique_id : this_unique_id })
.exec()
.then((found_document) => {
    // 2021-11-28 -- if we find a duplicate, we throw an error and handle it at the end
    // But remember, we want to return a HTTP status code 200 to AMS, so they will stop
    // re-sending this XML document.
    if (found_document != 'null') {
    throw new DocumentIsRedundantException(this_unique_id);
    }
});
// no catch() block because we want the exception to go to the top level
}

This gives me: UnhandledPromiseRejectionWarning

Maybe I’m thinking too much like Java instead of Javascript, but I was assuming that if I didn’t catch() the exception in that function, it would bubble up to the top level, which is where I want to deal with it. Also assumed it would interrupt the flow of the code at the line where I call the function.

Sadly, the uncaught exception does not interrupt the main thread of execution, so the document is saved, even when it is a duplicate.

So I’m left thinking the only way I can make this work is to return the Promise from the function and then have a then() block after the call to the document_is_duplicate function?

I dislike having to nest then() blocks inside of then() blocks, several levels deep. This seems like bad code. Is there another way?

>Solution :

Not sure why you want to throw an error if your document exists. Look for it, Mongoose will return a document if it exists, or null if it does not. Then simply await the result. Mongoose methods can be awaited, and if you add .exec() they even return a true Promise, which makes your life even easier :

const document_is_redundant = (this_model, unique_id) => this_model.findOne({ unique_id }).lean().exec();

// Now you use it this way
if( !(await document_is_redundant(AMS_945, unique_id))){ // If the returned value is not null
  console.log("Document is redundant! Aborting")
  return;
}
// Returned value was null
console.log("The document doesn't exist yet!")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading