apache / openwhisk

Apache OpenWhisk is an open source serverless cloud platform
https://openwhisk.apache.org/
Apache License 2.0
6.5k stars 1.16k forks source link

Error: Cannot find module 'requestretry' #640

Closed nicolelovecoding closed 8 years ago

nicolelovecoding commented 8 years ago

I used request and got the error "Error: connect ETIMEDOUT."

And then use node-request-retry, the error message is "Error: Cannot find module 'requestretry'"

Any way to solve the issue?

csantanapr commented 8 years ago

Hi @nicolelovecoding It will be helpful if you could provide steps to reproduce with some generic sample code.

I'm going to assume that you have a javascript action using default runtime nodejs 0.12 That you are using the request library provided by npm package request trying to do some type of http request to a web service or web site. And you are getting this error.

If you know that that the endpoint you are trying to reach is a valid one, and that it happens to timeout sometimes and you want to retry, you will need to write the logic, or use an npm package like node-request-retry

The problem is that the nodejs runtime only has a fix number of npm package already pre-installed and node-request-retry is not.

You can use an npm package that is not available by default by bundling 3rd party dependencies into your javascript action, take a look at the following article on how they use webpack to achieve this. https://developer.ibm.com/openwhisk/2016/03/17/bundling-openwhisk-actions-with-webpack/

For reference on which packages are available for default you can look at the source code or the reference doc

hope this helps, let us know how else we can help.

nicolelovecoding commented 8 years ago

My code is below:

const RequestRetry = require('node-request-retry'); const requestRetry = new RequestRetry(); const retryConditions = ['ETIMEDOUT'];

function main(msg) { const n = msg.n || 1; var url;

if (n % 2 == 1) url = 'https://******_/suqare?n=' + n; else url = 'https://**_****/suqare?n=' + n;

requestRetry.setRetryCodes(retryConditions); requestRetry.get(url, function(err, response, body) { if (response) { console.log('The number of request attempts: ' + response.attempts); whisk.done({msg: body}); } }); return whisk.async(); }

And still get the error message "Error: Cannot find module 'node-request-retry'"

csantanapr commented 8 years ago

That error message is accurate the npm package node-request-retry is not available.

This are the only npm packages pre-install and available:

sjfink commented 8 years ago

Yes, node-request-retry is not installed -- as @csantanapr posted above, you can work around this as follows:

The problem is that the nodejs runtime only has a fix number of npm package already pre-installe d and node-request-retry is not.

You can use an npm package that is not available by default by bundling 3rd party dependencies into your javascript action, take a look at the following article on how they use webpack to achieve this. https://developer.ibm.com/openwhisk/2016/03/17/bundling-openwhisk-actions-with-webpack/

@csantanapr I'd suggest we add this package to our base images.

csantanapr commented 8 years ago

I already provided an answer in my comment above https://github.com/openwhisk/openwhisk/issues/640#issuecomment-225763663

sjfink commented 8 years ago

reopening -- repurposing this as feature request to add requestretry to standard base image.

nicolelovecoding commented 8 years ago

Thanks, my another question is why I will have ETIMEDOUT error while using request get. I was following the example weather.js https://console.ng.bluemix.net/docs/openwhisk/openwhisk_actions.html#openwhisk_asynchrony_js to get info from another API. I works. But when I am calling my own end point it will timeout. I tried to call it in browser, it also works well. Here is my code:

const request = require('request');

function main(msg) {
   const n = msg.n || 1;
   var url;

   if (n % 2 == 1) 
      url = 'https://********/suqare?n=' + n;
   else 
      url = 'https://*******/suqare?n=' + n;

    request.get(url, function(error, response, body) {

        console.log(error);
        console.log(url);
        console.log(response);
        if (error)
           whisk.error();
        else
           whisk.done({msg: body});
    });
    return whisk.async();
}
sjfink commented 8 years ago

OK -- I believe I have reproduced this problem.

sjfink commented 8 years ago

The problem is that your URL is an internal IBM address (in the stage1/YS1 bluemix). Whisk actions can only talk to addresses in the public internet. You'd need to deploy your endpoint in the public bluemix.

nicolelovecoding commented 8 years ago

Ok, thanks!