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