A new IndyRaiseOuterException() function has been added to the IdGlobal unit:
procedure IndyRaiseOuterException(AOuterException: Exception);
This is a wrapper for the System.SysUtils.Exception.RaiseOuterException() class method, which is available on Windows only in Delphi/C++Builder 2009 and 2010, and for all platforms in Delphi/C++Builder XE and later.
To summarize, when a runtime error causes an Exception to being raised, and then a subsequent ‘except’ (Delphi) or ‘catch’ (C++) handler catches that Exception and raises/throws a new Exception, the original Exception is typically lost. To avoid that, the caught Exception can be “captured” into the InnerException property of the new Exception being raised, by passing the new Exception to Exception.RaiseOuterException() instead of to ‘raise’/’throw’ directly. A subsequent ‘except’/’catch’ block can then catch the new Exception and traverse its InnerException chain to discover earlier Exceptions.
On RTLs where Exception.RaiseOuterException() is not available, IndyRaiseOuterException() simply raises the specified Exception object as-is, as if ‘raise’ (Delphi) or ‘throw’ (C++) had been called directly.
Indy has been updated to call IndyRaiseOuterException() wherever it raises a new Exception object inside of an ‘except’ block rather than re-raising the original Exception.
For example, when connecting TIdSMTP to a server using UseTLS=utUseExplicitTLS (the SMTP “STARTTLS” command), a failure to negotiate a secure SSL/TLS session causes an EIdTLSClientTLSHandShakeFailed exception to be raised into the user’s code. That exception simply say “SSL negotiation failed” as its Message. Not very helpful. However, on supported RTLs, that exception’s InnerException property will now point at the earlier SSL/TLS exception that was raised during the handshake failure, such as EIdOSSLConnectError “Error connecting with SSL”, EIdOSSLUnderlyingCryptoError “certificate verify failed”, etc.