使用Node.js,Async和Formidable进行error handling

在下面的代码片段中,我想validation第一个asynchronous方法中的字段。

如果他们无效,我想立即返回一个错误给用户。

我怎么做?

var form = new formidable.IncomingForm(); async1.series([ function (callback) { form.parse(req); form.on('field', function (name, val) { // Get the fields }); form.on('fileBegin', function (name, file) { if (file.name !== "") { file.path = __dirname + '/upload/' + file.name; } }); callback(); }, function (callback) { form.on('file', function (name, file) { try { // Do something with the file using the fields retrieved from first async method } catch (err) { logger.info(err); } }); callback(); } ], function (err) { //the upload failed, there is nothing we can do, send a 500 if (err === "uploadFailed") { return res.send(500); } if (err) { throw err; } return res.status(200); }); 

我会提取窗体检查到一个函数:

 var form = new formidable.IncomingForm(); function check(name, cb, err){ return new Promise((res,rej)=>{ form.on('field', function (n, val) { if( n !== name) return; if( cb(val) ){ res(val); }else{ rej(err); } }); }); } form.parse( req ); 

所以现在我们可以执行检查和使用Promise.all来总结它们:

  Promise.all( check("username", val => val.length > 4,"username isnt valid"), check("password", val => true,"we need a password") ).then(_=>res.json({status:200})) .catch(err => res.json({err})); 

如果不是所有的参数都已经通过了,这将会无休止地等待。 所以让我们终止,如果它结束了:

 const ended = new Promise((_,rej)=>form.on("end",()=>rej("params required")); Promise.race( ended, Promise.all( check("username", val => val.length > 4,"username isnt valid"), check("password", val => true,"we need a password") ) ).then(_=>res.json({status:200})) .catch(err => res.json({err})); 

因此,我们可以创build一个良好的数据stream。 例如:

 const login = Promise.all( //usable as one liners check("username", val => val.length >= 8,"username invalid"), //or more extensible check("password", val =>{ if( val.length < 8 ) return false; //other checks console.log(password); return true; },"password invalid") //the field values are resolved by the promises so we can summarize them below ).then(([username,password])=> //a random (maybe async) call to evaluate the credentials checkAgainstDB(username,password) //we can directly fail here, err is "password invalid" or "username invalid" ).catch(err =>res.json({error:"login failed",details:err})); //another parameter can be extra handled const data = check("something",val => val.length); //we need to summarize all the possible paths (login /data in this case) to one that generates the result Promise.race( //here we join them together Promise.all(login,data) .then((l,d)=>res.json(whatever), //and we use the ended promise ( from above ) to end the whole thing ended //and at last the errors that can occur if the response ended or that have not been canceled early ).catch(e => res.json(e)); 
 var form = new formidable.IncomingForm(); async1.series([ function (callback) { form.parse(req); form.on('field', function (name, val) { if (!name || !val) { // the moment callback is called with an error, async will stop execution of any of the steps // in the series and execute the function provided as the last argument // idimoatic node, when calling the callback with instance of Error return callback(new Error('InvalidParams')); } /** * This is from async documentation: https://caolan.github.io/async/docs.html#series * Run the functions in the tasks collection in series, each one running once the previous function * has completed. If any functions in the series pass an error to its callback, no more functions are * run, and callback is immediately called with the value of the error. Otherwise, callback receives * an array of results when tasks have completed. */ }); form.on('fileBegin', function (name, file) { if (file.name !== "") { file.path = __dirname + '/upload/' + file.name; } }); form.on('end', function () { // call callback with null to specify there's no error // if there are some results, call it like callback(null, results); return callback(null); }); // if you call the callback immediately after registering event handlers for on('field') etc, // there will be no time for those events to be triggered, by that time, this function will be // done executing. //callback(); }, function (callback) { form.on('file', function (name, file) { try { // Do something with the file using the fields retrieved from first async method } catch (err) { logger.info(err); return callback(err); } }); // This should also not be called immediately //callback(); } ], function (err) { //the upload failed, there is nothing we can do, send a 500 if (err === "uploadFailed") { return res.send(500); } if (err.message === 'InvalidParams') { // This will be immediately returned to the user. return res.sendStatus(400); } if (err) { // I'm not sure if this was just for the example, but if not, you should not be throwing an error // at run time. throw err; } return res.status(200); }); 

我假设这是一个很好的validation的地方,因为这是田地进入的时候:

 form.on('field', function (name, val) { //if values are null if (!name || !val) { //pass the callback an error return callback("Values are null") } // Get the fields }); 

请让我知道这可不可以帮你。