izac
izac

Reputation: 89

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 ?

Upvotes: 2

Views: 7487

Answers (2)

izac
izac

Reputation: 89

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

Upvotes: 3

synthet1c
synthet1c

Reputation: 6282

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: '))

Upvotes: 1

Related Questions