Fair warning, It's my first time here at StackExchange. Be gentle.
I have a smallish (I think?) javascript project (which I'm using to learn) which is broken into modules. I'm using Bluebird for its more robust promises.
Each module has its own discrete responsibilities and draws on the features of others as needed. For example, I have a controller module that manages a user registration form and verification. This controller works together with a service module that handless communication with immediately adjacent modules. And then that service module uses a remote module which handles all remote communication with the server for the entire app via a third-party library. That library produces promises... so each of my modules handles their part of the resulting promises returned from server queries as it makes its way back to (in this case) the form controller.
Problem is, one part of my code is somehow managing to not handle a rejected promise. Bluebird is tossing out a "PossiblyUnhandledRejection" event. After having carefully checked for the usual suspects (typos, missed semicolons, missing braces, == instead of ===, forgotten returns/throws/catches, etc) and attempting to find explicit confirmation of whether or not I'm doing something wrong (or even if there is just a more standardized "accepted" pattern to use for this) I've got bupkis.
It looks a little like this:
/*** form controller ***/
/**
* setup and control form display
**/
function isUnameAvailable(formData) {
/**
* do stuff with data to collected from the form (or not, depending on
* form data)
*
* formData -> userDetails
**/
return formService.getUser(userDetails)
.then((data) => {
/**
* do stuff with data returned by the server
**/
// create new promise with results
return data;
}).catch((err) => {
/**
* attempt to recover from the error.
**/
// handle promise as an error in all remaining cases, by logging
// it and displaying an error dialog
eHandle.error(err);
// make it clear to bluebird that promises have been handled as
// intended (one of many "solutions" that have solved nothing)
return;
});
}
.
/*** form service module ***/
/**
* setup data to be held and provide methods for working with it
**/
function getUser(userDetails) {
/**
* do stuff with data to be sent to server (and more/or not, depending
* on various considerations)
**/
return remote.find('user', userDetails)
.then((data) => {
/**
* do stuff with data returned by server
**/
// if the results are properly formed and as expected create new
// promise containing data to be used by the controller
return data;
}).catch((err) => {
// create new rejected promise to be handled further up the
// chain. In this case, we can't do much with it here.
throw err;
});
}
.
/*** remote service module ***/
/**
* setup 3rd party module to communicate as required with remote server
**/
function find(remoteModel, searchCriteria) {
/**
* Collect data about the remote request to held handle rejections
**/
return thirdPartyLib[ remoteModel ].find(searchCriteria)
.then((data) => {
/**
* check and clean data returned by server
**/
// if the results are properly formed and as expected create
// new promise containing data to be used by the form service
return data;
}).catch((err) => {
/**
* check remote error and try to recover if possible (e.g. retry
* the server if it makes sense to). if not possible, format
* returned error data in a consistent form for use elsewhere in
* the application
**/
// create new rejected promise containing our custom error
// (which is, indeed, an instance of Error)
throw new CustomError(modifiedError);
});
}
The Bluebird docs are somewhat cryptic on the subject, saying "...because it is possible to handle a rejected promise at any time in the indeterminate future, some programming patterns will result in false positives. Because such programming patterns are not necessary and can always be refactored to never cause false positives, we recommend doing that to keep debugging as easy as possible ."
Well, gee willikers mister... that's certainly to the point but it's also entirely unhelpful. Is this one of those patterns? Where do I go to find out? What pattern should I be using? Several days of Google searches and browsing StackExchange later I have a number of sources seeming to imply what I'm doing should work but no exact answers to my specific questions. Worse, the pattern I describe above has actually been working nicely in other parts of the application only to mysteriously spew errors here. It actually still works... it's just filling the console with errors that shouldn't be there.
The Bluebird docs go on to give examples of ways to implement "more complex" error management in spite of these nebulously defined yet ever so noxious patterns it speaks of... tho I get the impression the suggestions given are meant more as sarcasm than actual advice.
So right now, I just want to know if I should be expecting the pattern above to work... or if I need to refactor the application (and in what way)? If I can at least figure out which way to Albuquerque maybe I can get to Las Vegas on my own from there (or I'll be back to figure out what other wrong turns I've made).
Aucun commentaire:
Enregistrer un commentaire