TL;DR
Use raise; instead of raise E;
Long version
In this code, when an exception caused by the ProduceMessage method got caught by the try … except construct and reached the Break statement in the Exception handler, an EAccesViolation occured:
procedure TProducerLoop.Run;
begin
while True do
begin
Connect;
while True do
begin
try
ProduceOneMessage;
except
on E: Exception do
begin
Break; // app crashes here
end;
end;
end;
Disconnect;
end;
end;
After many attempts to find the reason of the EAccessViolation, I found that it was caused by an raise E; instead of an raise; located in a method which got called by ProduceOneMessage. I removed the E and the EAccessViolation no longer occured.
function TBTMQProducer.InternalSend(const AMessage: IMessage;
const Destination: IDestination;
const CompletionListener: ICompletionListener): IMQProducer;
begin
try
Producer.Send(Destination, AMessage);
CompletionListener.OnMessage(AMessage);
except
on E: Exception do
begin
CompletionListener.OnException(AMessage, E);
raise E;
end;
end;
Result := Self;
end;
References:
https://marc.durdin.net/2012/10/how-not-to-re-raise-an-exception-in-delphi/
https://zerolith.com/delphi/on-delphi-exception-raising-re-raising-and-try-except-blocks.html