When a Delphi TCP server causes sudden EIdConnClosedGracefully Exceptions on the client
Posted by jpluimers on 2018/09/19
I always forget which sides of the connection throw this error, but the client side does as explained in [WayBack] delphi – Troubleshooting EIdConnClosedGracefully Exceptions? – Stack Overflow by [WayBack] Remy Lebeau the main Indy contributor:
EIdConnClosedGracefullymeans the other party … has disconnected its end of the connection. Once that exception has been raised, you cannot send more data to the other party. You must reconnect first.
In this case, the server side of a legacy Delphi application I temporarily took over was suddenly closing the connection because of these reasons:
- The OnExecute handler of the TIdTCPServer fired a TIdSync.SynchronizeMethod(MyMethod) call propagating to
- TThread.Synchronize queued the call to MyMethod
- MyMethod got called in a separate thread executing its code
- The MyMethod code threw an exception but didn’t log it (not even handle it)
- TThread.Synchronize got back in the calling thread and re-raised the exception
- The OnExecute handler of the TIdTCPServer didn’t catch log (not even handle) the exception
This caused this cascade in the underlying TIdThread.Execute around the TIdTCPServer connection instance:
- the underlying TIdThread.Execute to check TIdThread.HandleRunException which returns fals resuling
- TIdThread.Execute to call Terminate calling in turn
- TIdContext.AfterRun calling
- TIdCustomTCPServer.ContextDisconnected which then disconnects the TCP connection
Luckily, the OnDisconnectHandler of the TIdTCPServer did log the disconnect, but it would also destroy the TIdContext.Data and nil it.
However, that TIdContext.Data internally was referenced from other places as well, so other threads would now throw errors because they were doing a reference-after-free, a special case of Dangling Pointer bugs.
A few major thing here
- Always log Exceptions occurring in
IdTCPServerExecutemethod!- If you let Exceptions escape from a `IdTCPServerExecute` method, your connection will be killed.
- A killed connection is a “fail early, fail fast” mechanism that lets your users know soon that something is wrong.
- Be sure to have a mechanism in place to fix those things soon as well.
–jeroen






Remy Lebeau said
“Always log Exceptions occurring in IdTCPServerExecute method!” – alternatively, you can use the server’s OnException event, which is fired for any exception that escapes the OnConnect, OnExecute, or OnDisconnect event.
“If you let Exceptions escape from a
IdTCPServerExecutemethod, your connection will be killed.” – that is well-known and documented behavior (http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdTCPServer_OnExecute.html).jpluimers said
Thanks for the alternative and for pointing to the documentation.
[Archive.is] Internet Direct (Indy): TIdTCPServer.OnExecute Event: