I (relunctantly) agree with ChatGPT on this one - you should not modify the original exception, but instead you should raise a new exception that captures the original exception into the new exception's InnerException property.
However, the way that ChatGPT demonstrates this is wrong:
Firstly, SysUtils.Exception does not have a public SetInnerException() method. ChatGPT suggests defining a new class, but then doesn't use that class. And that class is just trying to replicate a feature that already exists natively in SysUtils.Exception.
Second, ChatGPT's approach does not release ownership of the original Exception, so the try..except will still try to free it when the except block exits, leaving the new Exception holding a dangling InnerException pointer to a now-dead Exception.
The correct way to capture an InnerException is to use the SysUtils.Exception.RaiseOuterException() method, eg:
try
sqhpartyroles.sql := fsqlhandle.buildsql;
sqhpartyroles.executesql;
except
Exception.RaiseOuterException(Exception.CreateFmt('error from sql %s', [sqhpartyroles.sql]));
end;
(I don't like this syntax, but it is what it is...)
Higher up the call chain, you can then catch the new Exception and traverse its InnerException chain if you want to report/log all of the individual error messages, eg
procedure MyForm.Application1Exception(Sender: TObject; E: Exception);
begin
repeat
// use E as needed, then...
E := E.InnerException;
until E = nil;
end;