I have a running HTTP server using Undertow in an embedded fashion. One thing I cannot figure out how to do is to prevent Undertow (or XNIO) from polluting the console log with useless IOException stack traces when the client abruptly disconnects during transmission.
What I want to do is emit a one-line note, only if diagnostics are enabled, that a connection ended with an exception and which handler was executing when that occurred. There is no recovery, of course, just note the fact and move on.
Unfortunately, these appear to be caught and dumped deep in the bowels of Undertow (or XNIO)code; catch clauses in my code never see these exceptions, so they have been swallowed before control returns to my handler.
Related
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 am working on a MySQL database and my question is two fold related to each other,
Do we require a rollback if an error were to occur during a transaction, as it would only commit changes if it reached the last line of execution (which would be the commit statment), if not dosent it automatically rollback
If there needs to be required a rollback then I was wondering if there was any new way introduced or any workaround for catching 'ALL' exceptions, similar to SQL server where you try and catch error and if any error occurs you rollback
My main Concerns are power outage, as it is common where I live and if the electricity is cut to the server (which would be nothing but a database installed on a PC shared through adhoc / wifi connection, not a dedicated server) in between a transaction, then useful statements might not execute like logging in transaction
If a transaction is not committed, and any of the following happen, it will be rolled back:
Power loss on your PC
Reboot on your PC
MySQL Server process crashes or is killed
Client application exits without committing transaction. The MySQL Server will detect the client is gone, and abort that client's session. This rolls back a transaction if one was open. This also happens if the network connection between client and server is dropped.
Fiddler is giving me the note:
This request was retried after a Receive operation failed.
It gives me this note on all my pages, except for my homepage.
How is this error created, what does it mean and most important, is there a fix?
This means your server failed to reuse a connection. This typically means that the server's configuration is non-optimal (or there's an interfering gateway), and the server is closing connections before they can be reused (a performance problem).
I wanted to figure out if a SSIS package would run without any problems by implementing a Health Check script task at the beginning of my package. I did this by iterating through the connection managers in the package and calling the acquireconnection method. If there is an exception acquiring connection, I handle it using catch block and assume that this error would not cause the package to fail. The package shows a successful run but an error gets logged in the “Execution Results/Progress” tab of the SSIS and leads to the failure of the corresponding ExecutePackage Task of the Parent package.
If I throw an exception explicitly within the try block, the parent package doesn’t fail. This failure seems to be happening only when an exception gets thrown by the execution of the acquire connection method.
I am looking understand why this happens and if there is a way I can prevent the parent package from failing whenever acquire connection call throws an exception. I am also open to an alternate approach to figure out if all connection managers within a package will work alright.
I have an application that uses c3p0 for connection pooling. When there is any kind of problem connecting to the database, I get an exception like this:
java.sql.SQLException: An SQLException was provoked by the following failure:
com.mchange.v2.resourcepool.ResourcePoolException: A ResourcePool cannot acquire
a new resource -- the factory or source appears to be down.
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at com.pontiflex.monitor.dao.ConnectionManager.getConfigReadOnlyDbConnection(Unknown Source)
at com.pontiflex.monitor.dao.MonitorServiceDAO.getLiveIOCountForOrganization(Unknown Source) at com.pontiflex.monitor.BillingMonitor.getComparisonValueForActivation(Unknown Source)
at com.pontiflex.monitor.AbstractMonitor.isMonitoringActive(Unknown Source)
at com.pontiflex.monitor.AbstractMonitor.generateAlerts(Unknown Source)
at com.pontiflex.monitor.AbstractMonitor.doMonitoring(Unknown Source)
at com.pontiflex.monitor.worker.MonitorWorker.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.mchange.v2.resourcepool.ResourcePoolException: A ResourcePool cannot
acquire a new resource -- the factory or source appears to be down.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1279)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
... 14 more
This same exception will occur regardless of what the problem is whether it be network connectivity issues, server issues (too many connections), or configuration problems. If I turn on debug logging for the mysql jdbc driver and c3p0, I get more information:
WARN com.mchange.v2.resourcepool.BasicResourcePool
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask#4e074784 --
Acquisition Attempt Failed!!! Clearing pending acquires. While trying
to acquire a needed new resource, we failed to succeed more than the
maximum number of allowed acquisition attempts (30). Last acquisition
attempt exception:
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Data
source rejected establishment of connection, message from server:
"Too many connections"
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:921)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1070)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775)
at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Is there anything I can do to get c3p0 to give me the underlying cause when it throws the ResourcePoolException without adjusting the logger configuration?
SQLException is the (checked) Exception that JDBC apis are permitted to throw, so c3p0 must "wrap" underlying Exceptions that ate not SQLExceptions in the usual way. Calling getCause() on these Exceptions will deliver the original Throwable if you want to check for something specific.
In the particular example you cite, something different is going on. The issue is that the Thread which is logging the Exception is not your client Thread. c3p0-internal Threads acquire Connections from the database. Your client Threads acquire Connections from the pool. The two activities are as uncoupled as c3p0 can manage -- that is the whole point of having a Connection pool. First, internal Threads perform a "round" of acquisition attempts (by default 30 attempts with a 1 sec delay between, but you can reconfigure if you want).
If ALL of the attempts to acquire a Connection fail, the c3p0 internal threads...
1) Log the failure, and the last Exception seen while trying. This is the second Exception you quote. Note that this is logged at WARNING, not a DEBUG level. If you have c3p0 logging at INFO -- which you should -- you'll see these messages. [If you want to see each individual Exception, all 30 of the Exceptions that must occur (under defailts) before declaring a failure, you need to turn logging to DEBUG (or FINE or ALL).]
2) After logging that an acquisition series has failed, c3p0 will interrupt wait()ing clients and signal a ResourcePoolException, which becomes gets in an SQLException. This is the first Exception you quote. A ResourcePoolException is signalled.
3) if breakAfterAcquireFailure is set to false (the default), the pool will recover from an acquisition failure. It will try again to acquire new Connections as new clients come in.. If breakAfterAcquireFailure is set to true, however, the pool will always respond to new client requests with an Exception.
Anyway, I hope this isn't entirely unhelpful. c3p0 could define a custom Exception type that would become the cause of the wrapped Exception delivered to clients, so clients could test for an acquisition failure in code, but for now at least it does not. (Sorry!)