Search code examples
delphiexceptiondelphi-7

Troubleshooting EIdConnClosedGracefully Exceptions?


The software we run using Delphi 7 generates and sends reports via email to various stakeholders. Of the roughly 30-40 reports transmitted daily, 2-4 different ones each day fail due to the exception: "EIdConnClosedGracefully"

I'm trying to trace why this is happening and how to catch this in the code. Here's what we have so far:

try
   // Code that Populates "mess" (a tIdMessage variable)

   if (not nSMTP.Connected) then
   begin
     nSMTP.Connect;
   end;

   try
     nSMTP.Send(mess);      
   except on E : Exception do
     begin
       resend := E.Message;
       // AutoReports_ExceptionMessage is a string that holds the Exception message
       AutoReports_ExceptionMessage := 'Attempt #1: ' + resend; 
     end;
   end;

   if (resend <> '') then   // If there is an exception triggered, resend the email
   begin
     try
       nSMTP.Send(mess);
     except on E : Exception do
       begin
         resend := E.Message;
         AutoReports_ExceptionMessage := 'Attempt #2: ' + resend;  
       end;
     end;
   end

finally
  mess.Free;
end;

Also, when the EIdConnClosedGracefully is triggered, it always displays "Attempt #2: Connection Closed Gracefully." and never "Attempt #1: Connection Closed Gracefully"

Any suggestions?


Solution

  • EIdConnClosedGracefully means the other party (the SMTP server in this case) 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. So in the code you showed, if attempt #1 fails due to a disconnected socket, attempt #2 will always fail.

    Try this instead:

    for Attempt := 1 to 2 do
    begin
      try
        //...
        if (not nSMTP.Connected) then
          nSMTP.Connect;
        nSMTP.Send(mess);
        AutoReports_ExceptionMessage := '';
        Break;
      except
        on E : Exception do
        begin
          AutoReports_ExceptionMessage := E.Message; 
          nSMTP.Disconnect;
        end;
      end;
    end; 
    

    Alternatively:

    try
      // ...
    
      if (not nSMTP.Connected) then
         nSMTP.Connect;
    
      try
        nSMTP.Send(mess);      
        AutoReports_ExceptionMessage := ''; 
      except
        on E : Exception do
        begin
          AutoReports_ExceptionMessage := E.Message; 
          nSMTP.Disconnect;      
          try
            nSMTP.Connect;      
            nSMTP.Send(mess);
            AutoReports_ExceptionMessage := ''; 
          except
            on E : Exception do
            begin
              AutoReports_ExceptionMessage := E.Message;
              nSMTP.Disconnect;      
            end;
          end;
        end;
      end;
    end;