node.js - can't catch Promise queue errors -


i'm setting node app have run series of asynchronous spawn tasks in order, i've got queue system set up. runs when reaches no errors. however, it's failing catch errors , log them when happen. here's right now:

function queue(tasks) {     let index = 0;     const runtask = (arg) => {         if (index >= tasks.length) {             return promise.resolve(arg);         }         return new promise((resolve, reject) => {             tasks[index++](arg).then(arg => resolve(runtask(arg))).catch(reject);         });     }     return runtask(); }  function customspawn(command, args) {     return () => new promise((resolve, reject) => {         const child = spawn(command, args, {windowsverbatimarguments: true});         child.on('close', code => {             if (code === 0) {                 resolve();             } else {                 reject();             }         });     }); } 

the queue built , executed this:

myqueue.push(customspawn('cmd.exe', ['/c', convertpath, filelist[i], '-interlace', 'line', '-chop', croppixels, '-resize', '300', outfile])); queue(myqueue).then(([cmd, args]) => {         console.log(cmd + ' finished - finished');     }).catch(function(error) {             console.error(error.stack);             }); 

the following error thrown: uncaught (in promise) typeerror: undefined not function(…)

sorry, can't quite understand queue function refactored using array.prototype.reduce. standard way chain things in compact way. following module models case , run in node. demonstrates how error handling works. assume want abort whole chain if there error?

'use strict'; const insp = require('util').inspect;  const size = 10; const throwat = 6;  var template = [1,2,3,4,5,6,7,8,9,]; var cmds = template.map((_, i) => ({cmd: `cmd ${_}`, args: [`arg1-${i}`, `arg2-${i}`]})); var queue = [];  // promise factory function makepromise (command, args) {   return () => new promise((resolve, reject) => {     settimeout(_ => {if(command.indexof(throwat) > 0) {       return reject(command);  // whatever passed here hit catch     }     console.log(`${command}\t${insp(args)}`);     resolve()     }, math.random() * 1000)   }) }  // populate queue cmds.foreach(c => queue.push(makepromise(c.cmd, c.args))); // execute , catch errors queue.reduce((q, p) => q.then(p), promise.resolve())   .catch(e => console.log(`error: ${e}`)); 

you can add re-try logic this...

// promise factory function makepromise (command, args) {   return () => new promise((resolve, reject) => {     settimeout(_ => {       if(command.indexof(throwat) > 0 && command.indexof('retry') === -1) {         return makepromise(command + 'retry', args)()           .then(_ => resolve(), e => reject(e));       }       console.log(`${command}\t${insp(args)}`);       resolve()     }, math.random() * 1000)   }) } 

error propagation

playing around this, noticed error thrown inside a resolve or reject callback result in reject of calling block being called, passing error object single argument. means error can thrown rather calling reject. has benefit of delivering stack trace also.

managing cascade

by adding reject callback each promise in chain, error propagation can managed if needed. if reject calback added however, must re-throw error if needs propagated.

here implementation of these 2 principles...

function makepromise2 (command, args) {   return (retry) => new promise((resolve, reject) => {     if(retry){       console.log(`throw @ ${command}`);       throw new error(`sorry, tried twice!`);     }     settimeout(_ => {       if(command.indexof(throwat) > 0) { /*         if(retry)   // throwing here not handled           throw new error(`sorry, tried best!`); */         return makepromise2(command, args)(true)           .then(resolve, reject);  // without fail silently       }       console.log(`${command}\t${insp(args)}`);       resolve();     }, math.random() * 1000)   }) }  function reject (cmd) {   return function reject (e) {   console.log(`re-throw @ ${cmd.cmd}`);   throw e;  // if have reject callback must propagate error }}  // populate queue cmds.foreach(c => queue.push(makepromise2(c.cmd, c.args))); // execute , catch errors // reject gives opportunity manage error cascade queue.reduce((q, p, i) => q.then(p, reject(cmds[i])), promise.resolve())   .catch(e => console.log(`catch...\n${e.stack}`)); 

Comments

Popular posts from this blog

unity3d - Rotate an object to face an opposite direction -

angular - Is it possible to get native element for formControl? -

javascript - Why jQuery Select box change event is now working? -