Zapier: Task timed out after 1.00 seconds - javascript

I am using the Zapier Code application in the javascript language, I am making a request in an api but in almost all attempts at the time of executing the script, I get the error message: "We had trouble sending your test through. Please try again. Error:
2018-03-09T14:32:54.748Z c0958e0a-23a6-11e8-9be1-a515bc24f853 Task timed out after 1.00 seconds". Sometimes script execution happens successfully, but most of the time it gives this error.
The calling code in the api I'm using is this:
var promises = [];
var retornoDaChamada;
promises.push(fetch(urls));
Promise.all(promises).then(function(res){
var blobPromises = [];
for (var i = res.length - 1; i >= 0; i--) {
blobPromises.push(res[i].text());
}
return Promise.all(blobPromises);
}).then(function(body){
retornoDaChamada=JSON.parse(body);
var titulosDaApi = [retornoDaChamada.length];
var duracao = [retornoDaChamada.length];
var ids = [retornoDaChamada.length];
for(var i=0; i<retornoDaChamada.length; i++){
titulosDaApi[i]=retornoDaChamada[i].title;
duracao[i]=milissegundosParaHorasMinutosSegundos(retornoDaChamada[i].files[0].fileInfo.duration);
ids[i]=retornoDaChamada[i].id;
}
var output = {titulosDaApi, duracao, ids};
callback(null, output);
}).catch(callback);
I read the documentation of the application Code and I kind of understood that free user only has the time of up to 1 second for calls in Api, is there any way I can get around this problem even though I am a free user?

David here, from the Zapier Platform team.
It's a little tough to understand the context of your code, but it looks like you're doing multiple HTTP requests. Due to their nature, they're a very slow operation. If you're doing more than 1 (maybe two if the external resource responds really quickly), you're unlikely to be able to fit everything into 1 second.
Sorry for the bad news!

Related

Stringify error with parallel.js

I am trying to parallelize a JavaScript project using parallel.js, but I am running into some kind of parsing problems.
The goal of the project is to have 9 ticket-sellers process customers in parallel. We have a working code right now, but the processing of the customers is still asynchronous, and we are trying to achieve the parallelization part using parallel.js.
My original code in JS before parallelizing is:
var ticketers = ["H", "M1", "M2", ...]; //There are 9 ticket-sellers
for(var i = 0; i < ticketers.length; i++) {
ticketerBehavior(i);
}
Where ticketers are the 9 ticket-sellers, and ticketerBehavior() is the function that takes care of what happens when a ticket-seller receives a customer.
Using the parallel.js documentation and examples, this is what we tried out:
var ticketBehav = function(ticketers){
for (var i = 0; i < ticketers.length; i++)
ticketerBehavior(i);
};
var p = new Parallel(100);
p.spawn(ticketBehav(ticketers)).then(console.log(ticketBehav(ticketers)));
However, when we run the program, it gives us this error:
/home/user/node_modules/paralleljs/lib/parallel.js:106
return preStr + 'process.on("message", function(e) {process.send(JSON.stringify((' + cb.toString() + ')(JSON.parse(e).data)))})';
^
TypeError: Cannot read property 'toString' of undefined
at Parallel.getWorkerSource (/home/user/node_modules/paralleljs/lib/parallel.js:106:91)
I tried googling the error but it does not return any results so far. I was a little confused on how to troubleshoot this error, since our data is technically serializable as JSON since they are only strings. Would a version compatibility cause any issues with running parallel.js as well?
Could anyone please advise me on where to start troubleshooting? Any tips/advice would be appreciated. Thank you!
Try this:
Pass your ticketers
For each ticket execute your function
Then return your data
p.spawn(function (ticketers) {return ticketBehav(data)}).then(function(data){ console.log(data) });

What caused process.hrtime() hanging in nodejs?

Here is the code:
var process = require('process')
var c = 0;
while (true) {
var t = process.hrtime();
console.log(++c);
}
Here is my environment:
nodejs v4.2.4, Ubuntu 14.04 LTS on Oracle VM virtualbox v5.0.4 r102546 running in Windows 7
This loop can only run about 60k to 80k times before it hangs. Nothing happens after that.
In my colleague's computer maybe 40k to 60k times. But shouldn't this loop continues forever?
I was first running a benchmark which tests avg execution time of setting up connections, so I can't just get the start time at first then end time after everything finished.
Is this related to the OS that I use?
Thanks if anyone knows the problem.
==========================================================
update 2016.4.13:
One day right after I raised this question, I realized what a stupid question it was. And it was not what I really want to do. So I'm gonna explain it further.
Here is the testing structure:
I have a node server which handles connections.Client will send a 'setup' event on 'connect' event. A Redis subscribe channel will be made at server side and then make some queries from db, then call client's callback of 'setup' event. Client disconnect socket in 'setup' callback, and reconnect on 'disconnect' event.
The client codes use socket.io-client to run in backend and cluster to simulate high concurrency.
Codes are like these:
(some of the functions are not listed here)
[server]
socket.on('setup', function(data, callback) {
queryFromDB();
subscribeToRedis();
callback();
}
[client]
var requests = 1000;
if (cluster.isMaster) {
for (var i = 0; i < 100; ++i) {
cluster.fork();
}
} else {
var count = 0;
var startTime = process.hrtime();
socket = io.connect(...);
socket.on('connect', function() {
socket.emit('setup', {arg1:'...', arg2:'...'}, function() {
var setupEndTime = process.hrtime();
calculateSetupTime(startTime, setupEndTime);
socket.disconnect();
}
}
socket.on('disconnect', function() {
if (count++ < requests) {
var disconnectEndTime = process.hrtime();
calculateSetupTime(startTime, disconnectEndTime);
socket.connect();
} else {
process.exit();
}
}
}
At first the connections could only make 500 or 600 times. Somehow I removed all the hrtime() codes, it made it to 1000 times. But later I raised the number of requests to like 2000 times (without hrtime() codes), it could not finish again.
I was totally confused. Yesterday I thought it was related to hrtime, but of course it wasn't, any infinite loop would hang. I was misled by hrtime.
But what's the problem now?
===================================================================
update 2016.4.19
I solved this problem.
The reason is my client codes use socket.disconnect and socket.connect to simulate a new user. This is wrong.
In this case server may not recognize the old socket disconnected. You have to delete your socket object and new another one.
So you may find the connection count does not equal to disconnection count, and this will prevent our code from disconnecting to redis, thus the whole loop hang because of redis not responsing.
Your code is an infinite loop - at some point this will always exhaust system resources and cause your application to hang.
Other than causing your application to hang, the code you have posted does very little else. Essentially, it could be described like this:
For the rest of eternity, or until my app hangs, (whichever happens first):
Get the current high-resolution real time, and then ignore it without doing anything with it.
Increment a number and log it
Repeat as quickly as possible
If this is really what you wanted to do - you have acheived it, but it will always hang at some point. Otherwise, you may want to explain your desired result further.

Saving To MongoDB In A Loop

i am having trouble saving a new record to mongoDB. i am pretty sure there is something i am using in my code that i don't fully understand and i was hoping someone might be able to help.
i am trying to save a new record to mongoDB for each of the cats. this code is for node.js
for(var x = 0; x < (cats.length - 1); x++){
if (!blocked){
console.log("x = "+x);
var memberMessage = new Message();
memberMessage.message = message.message;
memberMessage.recipient = room[x].userId;
memberMessage.save(function(err){
if (err) console.log(err);
console.log(memberMessage + " saved for "+cats[x].name);
});
}
});
}
i log the value of "cats" before the loop and i do get all the names i expect so i would think that looping through the array it would store a new record for each loop.
what seems to happen is that when i look ta the the database, it seems to have only saved for the last record for every loop cycle. i don't know how/why it would be doing that.
any help on this is appreciated because I'm new to node.js and mongoDB.
thanks.
That's because the save is actually a I/O operation which is Async. Now, the for loop is actually sync.
Think of it this way: your JS engine serially executes each line it sees. Assume these lines are kept one-after-another on a stack. When it comes to the save, it keeps it aside on a different stack (as it is an I/O operation, and thus would take time) and goes ahead with the rest of the loop. It so turns out that the engine would only check this new stack after it has completed every line on the older one. Therefore, the value of the variable cats will be the last item in the array. Thus, only the last value is saved.
To fight this tragedy, you can use mutiple methods:
Closures - Read More
You can make closure like so: cats.forEach()
Promises - Read More. There is a sweet library which promisifies the mongo driver to make it easier to work with.
Generators, etc. - Read More. Not ready for primetime yet.
Note about #2 - I'm not a contributor of the project, but do work with the author. I've been using the library for well over an year now, and it's fast and awesome!
You can use a batch create feature from mongoose:
var messages = [];
for(var x = 0; x < (cats.length - 1); x++) {
if (!blocked) {
var message = new Message();
message.message = message.message;
message.recipient = room[x].userId;
messages.push(message);
}
}
Message.create(messages, function (err) {
if (err) // ...
});

How to structure my code to return a callback?

So I've been stuck on this for quite a while. I asked a similar question here: How exactly does done() work and how can I loop executions inside done()?
but I guess my problem has changed a bit.
So the thing is, I'm loading a lot of streams and it's taking a while to process them all. So to make up for that, I want to at least load the streams that have already been processed onto my webpage, and continue processing stream of tweets at the same time.
loadTweets: function(username) {
$.ajax({
url: '/api/1.0/tweetsForUsername.php?username=' + username
}).done(function (data) {
var json = jQuery.parseJSON(data);
var jsonTweets = json['tweets'];
$.Mustache.load('/mustaches.php', function() {
for (var i = 0; i < jsonTweets.length; i++) {
var tweet = jsonTweets[i];
var optional_id = '_user_tweets';
$('#all-user-tweets').mustache('tweets_tweet', { tweet: tweet, optional_id: optional_id });
configureTweetSentiment(tweet);
configureTweetView(tweet);
}
});
});
}};
}
This is pretty much the structure to my code right now. I guess the problem is the for loop, because nothing will display until the for loop is done. So I have two questions.
How can I get the stream of tweets to display on my website as they're processed?
How can I make sure the Mustache.load() is only executed once while doing this?
The problem is that the UI manipulation and JS operations all run in the same thread. So to solve this problem you should just use a setTimeout function so that the JS operations are queued at the end of all UI operations. You can also pass a parameter for the timeinterval (around 4 ms) so that browsers with a slower JS engine can also perform smoothly.
...
var i = 0;
var timer = setInterval(function() {
var tweet = jsonTweets[i++];
var optional_id = '_user_tweets';
$('#all-user-tweets').mustache('tweets_tweet', {
tweet: tweet,
optional_id: optional_id
});
configureTweetSentiment(tweet);
configureTweetView(tweet);
if(i === jsonTweets.length){
clearInterval(timer);
}
}, 4); //Interval between loading tweets
...
NOTE
The solution is based on the following assumptions -
You are manipulating the dom with the configureTweetSentiment and the configureTweetView methods.
Ideally the solution provided above would not be the best solution. Instead you should create all html elements first in javascript only and at the end append the final html string to a div. You would see a drastic change in performance (Seriously!)
You don't want to use web workers because they are not supported in old browsers. If that's not the case and you are not manipulating the dom with the configure methods then web workers are the way to go for data intensive operations.

Get notified when JS breaks?

I have configured PHP to send me mails whenever there is an error. I would like to do the same with Javascript.
Also given the fact that this will be client side it is open to abuse.
What are good ways to get notified by mail when JS breaks in a web application?
Update:
Just to give some perspective, i usually load several js files including libraries (most of the time jQuery).
You can listen to the global onError event.
Note that you need to make sure it doesn't loop infinitely when it raises an error.
<script type="text/javascript">
var handlingError = false;
window.onerror = function() {
if(handlingError) return;
handlingError = true;
// process error
handlingError = false;
};
</script>
The code below relies on the global onError event, it does not require any external library and will work in any browser.
You should load it before any other script and make sure you have a server-side jserrorlogger.php script that picks up the error.
The code includes a very simple self-limiting mechanism: it will stop sending errors to the server after the 10th error. This comes in handy if your code gets stuck in a loop generating zillions of errors.
To avoid abuse you should include a similar self-limiting mechanism in your PHP code, for example by:
saving and updating a session variable with the error count and stop sending emails after X errors per session (while still writing them all down in your logs)
saving and updating a global variable with the errors-per-minute and stop sending emails when the threshold is exceeded
allowing only requests coming from authenticated users (applies only if your
application requires authentication)
you name it :)
Note that to better trace javascript errors you should wrap your relevant code in try/catch blocks and possibly use the printstacktrace function found here:
https://github.com/eriwen/javascript-stacktrace
<script type="text/javascript">
var globalOnError = (function() {
var logErrorCount = 0;
return function(err, url, line) {
logErrorCount++;
if (logErrorCount < 10) {
var msg = "";
if (typeof(err) === "object") {
if (err.message) {
// Extract data from webkit ErrorEvent object
url = err.filename;
line = err.lineno;
err = err.message;
} else {
// Handle strange cases where err is an object but not an ErrorEvent
buf = "";
for (var name in err) {
if (err.hasOwnProperty(name)) {
buf += name + "=" + err[name] + "&";
}
}
err = "(url encoded object): " + buf;
}
}
msg = "Unhandled exception ["+err+"] at line ["+line+"] url ["+url+"]";
var sc = document.createElement('script'); sc.type = 'text/javascript';
sc.src = 'jserrorlogger.php?msg='+encodeURIComponent(msg.substring(0, Math.min(800, msg.length)));
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sc, s);
}
return false;
}
})();
window.onerror = globalOnError;
</script>
You would wrap your entire program in a try/catch and send caught exceptions over AJAX to the server where an email could be generated. Short of that (and I wouldn't do that) the answer is "not really."
JA Auide has the basic idea. You could also go somewhat in between, ie.:
Write an AJAX "errorNotify" function that sends error details to the server so that they can be emailed to you.
Wrap certain parts of your code (the chunks you expect might someday have issues) with a try/catch which invokes errorNotify in the catch block.
If you were truly concerned about having 0 errors whatsoever, you'd then be stuff with try/catching your whole app, but I think just try/catching the key blocks will give you 80% of the value for 20% of the effort.
Just a note from a person that logs JavaScript errors.
The info that comes from window.onerror is very generic. Makes debugging hard and you have no idea what caused it.
User's plugins can also cause the issue. A very common one in certain Firebug versions was toString().
You want to make sure that you do not flood your server with calls, limit the amount of errors that can be sent page per page load.
Make sure to log page url with the error call, grab any other information you can too to make your life easier to debug.

Categories

Resources