How to handle the nodejs EMFILE exception without modifying ulimit? - asynchronous

I'm new to Node.JS and am stuck with an EMFILE error. I'm after a way of catching the EMFILE exception, and handling it in code.
There seems to be many questions about the "Error: EMFILE, Too many open files" error, but most answers seem to be along the lines of "Increase your ulimit".
My first question is, how do I catch this exception? When I run the below code with many connections, it raises the EMFILE error:
stream = net.createConnection(port, host);
stream.addListener('connect', function() {
return stream.write(request);
});
stream.addListener('data', function(data) {
return console.log(data);
});
stream.addListener('end', function() {
stream.end();
return callback();
});
stream.addListener('timeout', function() {
stream.destroy();
console.log("timeout");
return callback();
});
stream.addListener('error', function(e) {
console.log("this never gets called");
return
});
The exception isn't being caught in the 'error' listener. I've tried to wrap the above in a try{} catch (e) {} and nothing happens. I've used a callback method for createConnection, and it doesn't return any errors.
The only way I have been able to catch the exception is with:
process.on('uncaughtException', function(err) {
console.log(err);
});
which seems unsafe given it's catching everything.
And so my second question is: What is the "best practices" way to catch the error and retry the call?
I've looked at:
https://github.com/isaacs/npm/blob/master/lib/utils/graceful-fs.js
and
Simple nodejs http proxy fails with "too many open files"
as references, but I'm not sure how to apply the graceful method from npm to the createConnection call.
Thanks muchly!

Even if you could catch this exception, is there anything useful you would do about it? If you have a leak somewhere, you need to fix the leak, and if you have normal but very high load, then you'll need to handle this somehow. Either way, when you hit this condition, things are pretty bad in your node process.
Unfortunately, when you handle an uncaughtException event, the only safe thing to do is log an error message and then exit the process. The stack on which the exception was thrown is now gone, and deep internal confusion will likely soon result.
The best solution is to increase the number of file descriptors available to the process. The good news is that file descriptors are really cheap.

Related

Get detailed error for exception in SignalR Core Hub method execution

When I call Hub method I get frame response:
{"invocationId":"1","type":3,"error":"An error occurred while updating
the entries. See the inner exception for details."}
How can I get detailed error report (row and file where error occurred) without manually debugging and using step over and check where the code raise exception.
On net I found plenty codes where EnableDetailedErrors is used
services.AddSignalR(options =>
{
options.Hubs.EnableDetailedErrors = true;
});
but options (at least in version 1.0.0-alpha2-final) does not have property Hubs.
This is what you need to do in core (not sure the exact version this was added):
// signalR
services.AddSignalR(options =>
{
if (Environment.IsDevelopment()) {
options.EnableDetailedErrors = true;
}
});
It goes without saying that the reason this is disabled by default in production is for security reasons. So be careful not to expose things you may not wish 'hackers' to see in any of the exceptions you may throw.
Implementing the above setting will reveal a more detailed message in the browser console, whcih you can also see in the websocket debugging tab:
Quick tip:
I've set up SignalR twice now on ASPNetCore and I think I've made the same mistake both times:
// from typescript client arguments are passed like this
this.hubConnection.invoke('SendMessage', 'simon', 'hello');
// not like this
this.hubConnection.invoke('SendMessage', ['simon', 'hello']);
Also invoke will wait for a response, while send does not. So you may not see errors using send.
Currently the option to enable detailed errors is not implemented. There is an issue tracking this. My recommendation would be to turn on logging on the server side - the original exception will be logged there.

Check status of Meteor.js sync with server

meteor.js uses magic (ie: websockets) to sync the local db with the server. I have been searching for, but sofar have not been able to find, a way to see the status of the synchronisation. I would like the be able to check if a update for instance has been synced to the server. How could I do that?
thanks,
Paul
The callback associated with an insert/update/remove will be invoked with an error as its first argument. If error is defined, the server failed to make the modification. If it isn't defined, the modification succeeded.
Comments.update(commentId, {$set: {message: newMessage}}, function(error) {
if (error) {
console.log('it failed!');
} else {
console.log('it worked!');
}
});

SignalR fail method not called when user identity changed

I'm using SignalR but have run into a problem. When a connection is started in one browser window and then a user logs in in another browser window the User identity is changed (this causes the error 'System.InvalidOperationException: Unrecognized user identity. The user identity cannot change during an active SignalR connection' on the server when a method is called on the hub.
I'm using this code on the client:
proxy.server.analyze(content)
.done(function () {
console.log('Success!');
})
.always(function () {
console.log('This is always called!');
})
.fail(function (error) {
console.log('This is never called!');
});
When I'm seeing errors on the server the fail function is never being called so there appears to be no way on the client to handle this problem and stop and start the connection.
So is there a "best practice" way of handling this case? How can I detect on the client that the user identity has changed in another browser window and stop and re-start the connection?
This is a known issue.
It is fixed in the next release. Here's the issue that ended up also fixing your issue: https://github.com/SignalR/SignalR/issues/2106.
Lastly, in the next release (0.2.0) what will happen is the connection will throw an error and stop itself. Therefore you'll be able to handle your case via either the error handler or you can of course you can tie into the "disconnected" event.
If you're willing to try a pre-releases you can always pull from the offical source or webstack nightly (http://www.myget.org/F/aspnetwebstacknightly/)

Regarding AmazonClientException

I have to implement some error handling logic for DynamoDb errors. As said by AWS documentation, the errors are divided into client and server errors.
May be I am missing something in the object browser, but I don't understand how I will retrieve the "HttpStatusCode StatusCode" for the client errors (AmazonClientException) ?
This is just part of the server errors (AmazonServiceException) only.
As, I need to do some logging based on the error code, it seems that it can not be obtained from client exceptions currently.
There is no status code for a AmazonClientException which is not also an AmazonServiceException. If you have one from the service, it will be of the second type and you can get the status code. If you have one of the first type, it could be because you don't have an internet connection, or the service responded with a malformed response (perhaps not even HTTP, who knows!).
It's a little confusing that they decided to extend AmazonClientException with AmazonServiceException, because it means that (in java) you might have to do something like this:
try {
// ... make some dynamo requests ...
} catch (AmazonServiceException e) {
// aha, I can get at the status code!
} catch (AmazonClientException e) {
// OK, something really bizarre happened... perhaps dynamo is
// down, or I'm having internet issues.
}

SignalR not always ready after start().done()?

I have got a small project working with SignalR, however i am getting some very inconsistent behavior.
<script type="text/javascript">
$(function () {
var chat = $.connection.brewBattleHub;
$.connection.hub.start().done(function () {
$("#broadcast").click(function () {
// Call the chat method on the server
chat.server.roll($("#username").val(), $("#drinkname").val());
});
chat.server.sendMessage("SignalR loaded...");
});
});
</script>
When i load the page, sometimes i am seeing the message "SignalR loaded", other times i am not.
There's is some other functionality on the page also, and sometimes this does not work either. If i click buttons and make things happen enough it will eventually all come through in one go... from this point it is all golden and works perfectly.
does start().done()? not ensure it is all ready?
===
addendum, i am not referencing jquery mobile (google mentioned there is a bug when doing so)
I had a similar issue this week except that the code in .done() never ran. I enabled logging and nothing was ever logged. Checking the browser's console there were no errors. Looking in the browser's dev tools I could see that there was no network activity when I called start(). I confirmed that the proxy returned by $.connection.myhubclass had all my methods on it so I knew it could talk to the server and that the server side code was set up right.
After reviewing the code and documentation over and over again I was convinced that I wasn't doing anything wrong. SignalR is so simple it's pretty tough to do it wrong if you follow the examples. I beat my head on the desk for quite a long time trying to figure this out.
Then I noticed that if I ran SignalR's start method from the console it would work. That led me to believe that it was trying to start the connection too early. I solved my problems by changing the initialization code from this:
$.connection.hub.start().done(function () {
//Do interesting stuff
});
To this:
setTimeout(function () {
$.connection.hub.start().done(function () {
//Do interesting stuff
});
}, 5000);
I'm sure I can reduce that delay from 5 seconds to something shorter but the extra time appeared to be what was needed to let the browser get itself ready to create the connection. Once that delay was in there the logging started working, the connection came up, the server side OnConnected() ran and done() was run on the client.
After figuring this out I double checked the order of my javascript loading, thinking maybe I was loading something out of order but the order is right according to the SignalR samples. I load jQuery, SignalR, /signalr/hubs, then my script file that initializes everything.
I am open to suggestions as to why that delay was needed. I don't see it in any of the docs so I know it could be something I did. Fortunately for this page a minor delay before starting up SignalR is not a problem.
Try enabling SignalR logging to help debug your issue. You might also want to add a fail handler in case start isn't succeeding (though this is unlikely). Once you have done this you can look through your browser's F12 tools to look at the JS and network logs.
<script type="text/javascript">
$(function () {
$.connection.hub.logging = true;
var chat = $.connection.brewBattleHub;
$.connection.hub.start().done(function () {
$("#broadcast").click(function () {
// Call the chat method on the server
chat.server.roll($("#username").val(), $("#drinkname").val());
});
chat.server.sendMessage("SignalR loaded...");
}).fail(function (reason) {
console.log("SignalR connection failed: " + reason);
});
});
</script>
I've found a solution (as far by my problem).
I had SignalR loading for some 7-8 seconds on IE11, I've tried to "debug" it in console and I've found the cause of the loading delay:
[13:13:04 GMT+0200 (...)] SignalR: Binding to iframe's load event.
[13:13:09 GMT+0200 (...)] SignalR: foreverFrame timed out when trying to connect.
[13:13:09 GMT+0200 (...)] SignalR: Stopping forever frame.
It took 5 sec. to try to load iframe.
The neat solution is to turn the iframe off, as IE11 can normally use longPolling:
$.connection.hub.start(({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] }))
I had a similar issue that only appeared when trying to reestablish the connection after disconnect. I called start() from the disconnect handler and then tried to send a message from start.done(). Then I got an error message that SignalR was not ready.
I noticed in the log that start.done() resolved immediately so there was in my case a call from disconnect to start and then to send. I added a setTimeout in the disconnect handler so that start and send were decoupled from disconnect. That resolved the issue for me.

Resources