Managing Exceptions in Indy TIdTCPServer and TIdTCPClient
I have read in other post of this forum and in other places that in Indy components the exceptions (descendant from EIdException) are internally managed.
For this reason, in the TCPServer Execute method there is no need to use a try - catch block.
But what happens if in the TCPServer Execute method another kind of exception occurs?
In my server application, I have put a TIdTCPServer component on the main form, if something bad happens inside its Execute method and I don't manage it, the server stops.
Obviously I need the server running so I use a try - catch block and if there is an exception (any kind of exception), I restart the server.
I don't know if this is the best thing to do.
Sometimes, with the server application running in the IDE, I got the error
Project CallMonitor.exe raised exception class EIdSocketError with message 'Socket Error # 10054 - Connection reset by peer.'.
probably caused by the client running on the same computer (not in the IDE).
The application execution is blocked and If I break, code is stopped in IdStack file where there is the big READ ME!!! about exception 10038.
I press F9 and the application continues running.
For me it is not very clear what happens. My try - catch block is effective in this situation? Or is it useless or harmful?
I have to filter Indy exceptions and other exceptions?
On the client side, in my application there is a TIdTCPClient object in the main form and the connection to the server is managed in the main thread. Then there is another thread to manage communication with the server. In the communication thread Execute method I have a try - catch block and a loop in which I send a request to the server every 2 seconds or when the user asks for data and I decode the server answer.
If there is a EIdReadTimeout exception, i terminate the thread and I restart it. For other exception, I terminate the thread, I disconnect/connect the TIdTCPClient and I restart the thread.
I think this is a different situation because in the server the exception was managed inside the TIdTCPServer thread while in the client the exception is managed in a thread that just uses the TCPClient->Socket to communicate with the server, is it right?
Any answer/comment/suggestion is appreciated.
in the TCPServer Execute method there is no need to use a try - catch block. But what happens if in the TCPServer Execute method another kind of exception occurs?
ANY uncaught exception that is allowed to escape from the OnConnect or OnExecute event back into TIdTCPServer will cause the calling TIdContext thread to stop running. It will close its associated client Connection during its cleanup, firing the OnDisconnect event. And then the OnException event will be fired afterwards.
In my server application, I have put a TIdTCPServer component on the main form, if something bad happens inside its Execute method and I don't manage it, the server stops.
The server as a whole does not stop. Only the calling TIdContext thread is stopped.
Obviously I need the server running so I use a try - catch block and if there is an exception (any kind of exception), I restart the server.
It is not necessary to restart the whole server on any exception. Only on exceptions that invalidate/corrupt something that your app needs to function properly.
Sometimes, with the server application running in the IDE, I got the error
Project CallMonitor.exe raised exception class EIdSocketError with message 'Socket Error # 10054 - Connection reset by peer.'.
That is a perfectly normal socket error. That will not kill your whole server.
If you go into your IDE's debugger settings, there is an option to ignore Indy "silent" exceptions (derived from EIdSilentException, such as EIdConnClosedGracefully). Or, you can also tell the debugger specific exception types to ignore, such as EIdSocketError.
The application execution is blocked ... I press F9 and the application continues running.
Exactly. Not a fatal error. The blockage is only in the debugger, it is letting you examine the exception and decide what to do with it.
For me it is not very clear what happens. My try - catch block is effective in this situation?
The IDE debugger catches exceptions before your code does. When you press F9 to continue execution, the exception will be passed back to your code, and the appropriate catch will handle it normally.
Or is it useless or harmful?
No.
I have to filter Indy exceptions and other exceptions?
IF you catch exceptions at all, handle the ones you need, and then you should re-throw any Indy-specific exceptions you caught (all Indy exceptions are derived from EIdException for easy identification), let the server handle them. If you don't, then you should disconnect the calling Connection yourself and exit the event handler gracefully. Either way, the server will then cleanup the rest as needed.
On the client side, in my application there is a TIdTCPClient object in the main form and the connection to the server is managed in the main thread. Then there is another thread to manage communication with the server.
I would move the connection management into the worker thread as well. Connect, communicate, disconnect, repeat if needed, should all be in one thread.
In the communication thread Execute method I have a try - catch block and a loop in which I send a request to the server every 2 seconds or when the user asks for data and I decode the server answer. If there is a EIdReadTimeout exception, i terminate the thread and I restart it.
If an actual read operation times out, the state of the communication is unknown and likely unrecoverable, as you don't know which byte was the one that timed out. So you should disconnect and re-connect, not just restart the thread. The only time you wouldn't need a full re-connect is if you are handling the timeout wait yourself in between messages, and know the communication hasn't been corrupted. In which case, simply restarting the thread without a full re-connect is not likely to solve the timeout condition. It would be simpler to just re-try the wait operation again.
For other exception, I terminate the thread, I disconnect/connect the TIdTCPClient and I restart the thread.
If the connect/disconnect logic were moved into the thread, they could be done in a loop, then there would be no need to restart the thread itself. Threads are expensive to create/destroy (from the OS's perspective), so try to reuse threads when possible.
I think this is a different situation because in the server the exception was managed inside the TIdTCPServer thread while in the client the exception is managed in a thread that just uses the TCPClient->Socket to communicate with the server, is it right?
Yes.
Hope you are all doing good. I have a problem with SSRS as it is stuck in the loading state (tried with several different browsers) even though executionlog3 says execution has been completed. I agree with executionlog3 as I don't see any running query in the database.
When I check SSRS logs, I see below error corresponds to the execution I do.
I have checked out a couple of websites but did not get any benefit. Any of you have an idea what could be the issue?
ERROR: Failed in BaseWorkerRequest::SendHttpResponse(bool), exception=System.ArgumentException: Value does not fall within the expected range.
This is most often because some intermediary has concluded that the TCP socket is not in use and has been closed. Because SSRS and the browser are both completely ignorant to the fact that the TCP socket is now closed, the server will continue to work on the report and the browser will continue to wait for it. The server will error out when it finally attempts to send the completed file over the socket only to find the session no longer exists, while the browser will continue to load until it times out.
Check to see if your requests are passing through a load balancer or firewall. Attempt connecting directly to the SSRS server to see if you can replicate the issue if they're not in the way. If it ends up being something like a load balancer, talk to the admins and ask them to extend the session timeout.
Alternatively, execute long running reports as subscriptions.
I'm basically checking all the routes via request module with mocha.
https://www.npmjs.com/package/request
I'm doing a stress test, by opening two console windows side by side and running them simultaneously. Most of the time tests are successful, but then an instant comes when the tests fail without timeout error, and from postman I've this specific route that stops responding.
it happens once in around 7 times, and I'm wondering what I could do to figure this out.
Edit:
Increased to 4 console windows running tests simultaneously, they ran fine couple of times but then start to timeout.
even no console output on app.get, app.post etc. routes.
Any suggestions?
Edit
Caught some request errors based on the suggestion within tests.
Uncaught AssertionError: { [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' } == null
The corresponding code for the above error is
request({url: endpoint + "/SignIn?emailAddress=" + emailAddress + "&password=" + password}, function (error, response, body) {
assert.equal(error, null);
Edit 2
Dig further deep with console statements and noticed the mysql connection callback was not called. Attaching a screenshot and noticing some connection limit, is it because of this? I'm using connection pools though.
logs says forcing close of threads.
Probable Answer:
This thread helped with the issue.
https://github.com/felixge/node-mysql/issues/405
I set the waitForConnections: false and then started to see the error ->
[Error: No connections available.]
so it seems to me that system was waiting for the connections but test runner didn't wait and ended up with timeout error.
It also seems there's some limit on the maximum number of connections, though I was calling release on connections after each query, not sure how this works on production systems out there? do we have a limit there?
You are running out of tcp connections. You need to make few changes in system and application level, to make it handle more load.
1. Change your connection setting to keepAlive, wherever possible.
2. On unix, you have ulimit, i.e., the maximum number of file handles that any process can hold at any instant. Remember, in unix every socket is also a file.
3. Manage your time out settings, based on the response time of your database server or another web server.
You'll have to do similar changes at each level of handling request, if you have a multi-tier architecture.
I'm running a Node server connecting to MySQL via the node-mysql module. Connecting to and querying MySQL works great initially without any errors, however, the first query after leaving the Node server idle for a couple hours results in an error. The error is the familiar read ECONNRESET, coming from the depths of the node-mysql module.
A stack trace (note that the three entries of the trace belong to my app's error reporting code):
Error
at exports.Error.utils.createClass.init (D:\home\site\wwwroot\errors.js:180:16)
at new newclass (D:\home\site\wwwroot\utils.js:68:14)
at Query._callback (D:\home\site\wwwroot\db.js:281:21)
at Query.Sequence.end (D:\home\site\wwwroot\node_modules\mysql\lib\protocol\sequences\Sequence.js:78:24)
at Protocol.handleNetworkError (D:\home\site\wwwroot\node_modules\mysql\lib\protocol\Protocol.js:271:14)
at PoolConnection.Connection._handleNetworkError (D:\home\site\wwwroot\node_modules\mysql\lib\Connection.js:269:18)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:415:13)
This error happens both on my cloud Node server and MySQL server as well as a local setup of both.
My questions:
Does this problem appear to be a disconnection of Node's connection to my MySQL server(s), perhaps due to a connection lifetime limitation?
When using connection pools, node-mysql is supposed to gracefully handle disconnections and prune them from the pool. Is it not aware of the disconnect until I make a query, thus making the error unavoidable?
Considering that I see the "read ECONNRESET" error a lot in other StackOverflow posts, should I be looking elsewhere from MySQL to diagnose the problem?
Update: After more browsing, I think my issue is a duplicate of this one. It appears his connection is disconnecting as well, but no one has suggested how to keep the connection alive or how to address the error outside of failing on the first query back.
I reached out to the node-mysql folks on their Github page and got some firm answers.
MySQL does indeed prune idle connections. There's a MySQL variable "wait_timeout" that sets the number of second before timeout and the default is 8 hours. We can set the default to be much larger than that. Use show variables like 'wait_timeout'; to view your timeout setting and set wait_timeout=28800; to change it.
According to this issue, node-mysql doesn't prune pool connections after these sorts of disconnections. The module developers recommended using a heartbeat to keep the connection alive such as calling SELECT 1; on an interval. They also recommended using the node-pool module and its idleTimeoutMillis option to automatically prune idle connections.
If this happens when establishing a single reused connection, it can be avoided by establishing a connection pool instead.
For example, if you're doing something like this...
var db = require('mysql')
.createConnection({...})
.connect(function(err){});
do this instead...
var db = require('mysql')
.createPool({...});
Does this problem appear to be a disconnection of Node's connection to my MySQL server(s), perhaps due to a connection lifetime limitation?
Yes. The server has closed its end of the connection.
When using connection pools, node-mysql is supposed to gracefully handle disconnections and prune them from the pool. Is it not aware of the disconnect until I make a query, thus making the error unavoidable?
Correct, but it should handle the error internally, not pass it back to you. This appears to be a bug in node-mysql. Report it.
Considering that I see the "read ECONNRESET" error a lot in other StackOverflow posts, should I be looking elsewhere from MySQL to diagnose the problem?
It is either a bug in the node-MySQL connection pool implementation, o else you haven't configured it properly to detect failures.
I have been also facing the same issue. Apparently it was happening because one of the backend process has been triggered on table which was being referred in my api.
This caused table to go in lock wait state and my query request got failed with connection reset. Though i'm wondering why i didn't receive lock wait error .
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm getting a SQL Server error:
A transport-level error has occurred
when receiving results from the
server. (provider: Shared Memory
Provider, error: 0 - The handle is
invalid.)
I'm running Sql Server 2008 SP1, Windows 2008 Standard 64 bit.
It's a .Net 4.0 web application. It happens when a request is made to the server. It's intermittent. Any idea how I can resolve it?
The database connection is closed by the database server. The connection remains valid in the connection pool of your app; as a result, when you pickup the shared connection string and try to execute it's not able to reach the database. If you are developing Visual Studio, simply close the temporary web server on your task bar.
If it happens in production, resetting your application pool for your web site should recycle the connection pool.
Try the following command on the command prompt:
netsh interface tcp set global autotuning=disabled
This turns off the auto scaling abilities of the network stack
I had the same problem. I restarted Visual Studio and that fixed the problem
Transport level errors are often linked to the connection to sql server being broken ... usually network.
Timeout Expired is usually thrown when a sql query takes too long to run.
So few options can be :
Check for the connection in VPN (if used) or any other tool
Restart IIS
Restart machine
Optimize sql queries.
For those not using IIS, I had this issue when debugging with Visual Studio 2010. I ended all of the debugger processes: WebDev.WebServer40.EXE which solved the issue.
All you need is to Stop the ASP.NET Development Server and run the project again
If you are connected to your database via Microsoft SQL Server Management, close all your connections and retry.
Had this error when connected to another Azure Database, and worked for me when closed it.
Still don't know why ..
Look at the MSDN blog which details out this error:
Removing Connections
The connection pooler removes a connection from the pool after it has
been idle for a long time, or if the pooler detects that the
connection with the server has been severed.
Note that a severed connection can be detected only after attempting
to communicate with the server. If a connection is found that is no
longer connected to the server, it is marked as invalid.
Invalid connections are removed from the connection pool only when
they are closed or reclaimed.
If a connection exists to a server that has disappeared, this
connection can be drawn from the pool even if the connection pooler
has not detected the severed connection and marked it as invalid.
This is the case because the overhead of checking that the connection
is still valid would eliminate the benefits of having a pooler by
causing another round trip to the server to occur.
When this occurs, the first attempt to use the connection will detect
that the connection has been severed, and an exception is thrown.
Basically what you are seeing is that exception in the last sentence.
A connection is taken from the connection pool, the application does
not know that the physical connection is gone, an attempt to use it is
done under the assumption that the physical connection is still there.
And you get your exception.
There are a few common reasons for this.
The server has been restarted, this will close the existing connections.
In this case, have a look at the SQL Server log, usually found at:
C:\Program Files\Microsoft SQL Server\\MSSQL\LOG
If the timestamp for startup is very recent, then we can suspect that
this is what caused the error. Try to correlate this timestamp with
the time of exception.
2009-04-16 11:32:15.62 Server Logging SQL Server messages in file
‘C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\ERRORLOG’.
Someone or something has killed the SPID that is being used.
Again, take a look in the SQL Server log. If you find a kill, try to
correlate this timestamp with the time of exception.
2009-04-16 11:34:09.57 spidXX Process ID XX was killed by
hostname xxxxx, host process ID XXXX.
There is a failover (in a mirror setup for example) again, take a look in the SQL Server log.
If there is a failover, try to correlate this timestamp with the time
of exception.
2009-04-16 11:35:12.93 spidXX The mirrored database “” is changing roles from “PRINCIPAL” to “MIRROR” due to
Failover.
Was getting this, always after about 5 minutes of operation. Investigated and found that a warning from e1iexpress always occurred before the failure. This apparently is an error having to do with certain TCP/IP adapters. But changing from WiFi to hardwired didn't affect it.
So tried Plan B and restarted Visual Studio. Then it worked fine.
On closer study I noticed that, when working correctly, the message The Thread '<No Name>' has exited with code 0 occurred at almost exactly the time the run crashed in previous attempts. Some Googling reveals that that message comes up when (among other things) the server is trimming the thread pool.
Presumably there was a bogus thread in the thread pool and every time the server attempted to "trim" it it took the app down.
You get this message when your script make SQL Service stopped for some reasons. so if you start SQL Service again perhaps your problem will be resolved.
I know this may not help everyone (who knows, maybe yes), but I had the same problem and after some time, we realized that the cause was something out of the code itself.
The computer trying to reach the server, was in another network, the connection could be established but then dropped.
The way we used to fix it, was to add a static route to the computer, allowing direct access to the server without passing thru the firewall.
route add –p YourServerNetwork mask NetworkMask Router
Sample:
route add –p 172.16.12.0 mask 255.255.255.0 192.168.11.2
I hope it helps someone, it's better to have this, at least as a clue, so if you face it, you know how to solve it.
I got the same error in Visual Studion 2012 development environment, stopped the IIS Express and rerun the application, it started working.
I had the same issue. I solved it, truncating the SQL Server LOG.
Check doing that, and then tell us, if this solution helped you.
For me the solution was totally different.
In my case I had an objectsource which required a datetimestamp parameter. Even though that ODS parameter ConvertEmptyStringToNull was true 1/1/0001 was being passed to SelectMethod. That in turn caused a sql datetime overflow exception when that datetime was passed to the sql server.
Added an additional check for datetime.year != 0001 and that solved it for me.
Weird that it would throw a transport level error and not a datetime overflow error.
Anyways..
In my case the "SQL Server" Server service stopped. When I restarted the service that enabled me to run the query and eliminate the error.
Its also a good idea to examine your query to find out why the query made this service stop
For me the answer is to upgrade the OS from 2008R2 to 2012R2, the solution of iisreset or restart apppool didn't work for me.
I also tried to turn of TCP Chimney Offload setting, but I didn't restart the server because it is a production server, which didn't work either.
We encountered this error recently between our business server and our database server.
The solution for us was to disable "IP Offloading" on the network interfaces.
Then the error went away.
One of the reason I found for this error is 'Packet Size=xxxxx' in connection string. if the value of xxxx is too large, we will see this error. Either remove this value and let SQL server handle it or keep it low, depending on the network capabilities.
It happened to me when I was trying to restore a SQL database and checked following Check Box in Options tab,
As it's a stand alone database server just closing down SSMS and reopening it solved the issue for me.
This occurs when the database is dropped and re-created some shared resources is still considering the database still exists, so when you re-run execute query to create tables in the database after it was re-created the error will not show again and Command(s) completed successfully. message will show instead of the error message Msg 233, Level 20, State 0, Line 0 A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.).
Simply ignore this error when you are dropping and recreating databases and re-execute your DDL queries with no worries.
I faced the same issue recently, but i was not able to get answer in google.
So thought of sharing it here, so that it can help someone in future.
Error:
While executing query the query will provide few output then it will throw below error.
"Transport level error has occurred when receiving output from
server(TCP:provider,error:0- specified network name is no longer
available"
Solution:
Check the provider of that linked server
In that provider properties ,Enable "Allow inprocess" option for that particular provider to fix the issue.