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