简体   繁体   中英

request-promise Unhandled rejection RequestError: Error: ETIMEDOUT

Hi i try to write some download function by promise request, but if i have a timeout i cant handled this error , i try meny example but still have this error

Unhandled rejection RequestError: Error: ETIMEDOUT
    at new RequestError (/home/parse/node_modules/request-promise-core/lib/errors.js:14:15)
    at Request.plumbing.callback (/home/parse/node_modules/request-promise-core/lib/plumbing.js:87:29)
    at Request.RP$callback [as _callback] (/home/parse/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at self.callback (/home/parse/node_modules/request/request.js:186:22)
    at emitOne (events.js:101:20)
    at Request.emit (events.js:191:7)
    at Timeout._onTimeout (/home/parse/node_modules/request/request.js:816:16)
    at ontimeout (timers.js:380:14)
    at tryOnTimeout (timers.js:244:5)
    at Timer.listOnTimeout (timers.js:214:5)

my code

function for download :

function downloadPhoto(url,uploadUrl,name){
   return new Promise(function(resolve, reject){
        rp(url,{timeout:15000},function(e){if(e) reject(e);}).on('error', function(e){return reject(e);}).pipe(fs.createWriteStream(name+'.jpg')).on('finish', () => {
        //console.log('done Download photo');
         return resolve();
    });
  });

}

call this function

function sndPht(url,uploadUrl){
    return new Promise(function(resolve, reject){
      return downloadPhoto(url,uploadUrl,name).then(function(){
             ..... some logic .....  
        }).catch(function(err){
            return reject(err);
        });
}

for many file i call function in bluebird js map :

Promise.map(photos, function(photo) {
  if(photo.type === 'photo'){
    return sndPht(photo,uploadUrl);
  }  
},{concurrency: 1});

What i do wrong ?

I have a solution , if you use a request-promise you shout create promise and return him and catch the exeption , it dont work with pipe like in my case so we need change the function download like

function downloadPhoto(url){
  var options = {
      uri:url,
      timeout:10000,
      encoding: 'binary'
  };

  return rp(options);
}

and then we can use it like

return downloadPhoto(url).then(function(file){
      fs.writeFileSync(name+'.jpg', file, 'binary');
    }).catch(function(err){
     console.log(err);
});

and we can use map

Promise.map(photos, function(photo) {
  if(photo.type === 'photo'){
    return sndPht(photo,uploadUrl);
  }  
},{concurrency: 1});

but if you need downlod large file you need use request with calback's

You can use Promise.race to use the value from the first promise that resolves or rejects.

Using this technique we can have an error that will timeout after a period of time if the download is taking too long. The downloadPhoto Promise will still resolve, but it will not be handled

 const images = [ { url: 'www.foo.com', uploadUrl: '/foo', name: 'foo' } , { url: 'www.bar.com', uploadUrl: '/bar', name: 'bar' } , { url: 'www.baz.com', uploadUrl: '/baz', name: 'baz' } ] const promiseTimeout = (delay, promise) => Promise.race([ new Promise((resolve, reject) => setTimeout(resolve, delay, { status: 'error', msg: 'took too long!' }) ), promise ]) const downloadPhoto = ({ url, uploadUrl, name }) => promiseTimeout( 1000, new Promise((resolve, reject) => { setTimeout(resolve, 3000, { status: 'success', msg: `this will never resolve ${url}` }) }) ) // map images array [...image] into [...Promise(image)] const imagePromises = images.map(downloadPhoto) // resolve all promises Promise.all(imagePromises) // called once all promises are resolved with array of results .then(images => { // map over the resolved images and do further processing images.map(console.log.bind(console, 'Image resolved')) }) // promises no longer reject, you will need to look at the status .catch(console.log.bind(console, 'Error: ')) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM