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.
I have configured User Defined datasource for MySQL database using below.
WebSphere 8.5
mysql-cluster-gpl-7.4.6
mysql-connector-java-5.1.9-bin.jar
Implementation Class in Provider :
com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
However, I get below exception for JTA transaction spanning MySQL and Oracle datasource operation for MySQL datasource.
E WTRN0063E: An illegal attempt to commit a one phase capable
resource with existing two phase capable resources has occurred.
As per docs, MySQL supports XA-transaction, My driver is implementing XADatasource.
Can you confirm what is it that I am missing.
May be datasource configuration that it is not two phase capable transactional resources?
I have also used ENGINE=INNODB to create MySQL table.
It sounds like you need to configure your datasource to be XA capable on the WebSphere side. By default, WAS datasource will not implement javax.sql.XADataSource.
See this WAS 8.5 documentation link (section 8.e) to verify your config is using an XA datasource:
http://www-01.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.doc/ae/tdat_ccrtpds.html?cp=SSEQTP_8.5.5%2F1-3-0-23-3-0-7-1
When running code first migrations with MySQL the migration completes successfully but as soon as context is accesses and i either try to fetch or add data i get an exception.
An unhandled exception of type 'System.ArgumentException' occurred in EntityFramework.dll
Additional information: The underlying provider does not support the type 'nvarchar(max)'.
Automatic migrations work without any problem :(
I'm new in OCCI programming and I have one question.
I'm writing a Linux daemon, which connetcts to an Oracle database. Sometimes database server breaks connection(or db admin kills session), in that case I catch an SQLException. My question is: how should I correctly terminate OCCI connection after catching an exception?
P.S. terminateConnection method throws the same exception and I get an endless loop or uncatched exception with programm aborting.
When my grails application faces high load, I encounter some SQLException :
java.sql.SQLException: Can't call commit when autocommit=true
This problem appears only when the number of connection on the application raises.
I'm using grails 1.2.2 and mysql 5.1
Does anybody already faces such kind of problem ?
Thanks in advance.