TidMessage异常处理不适用于EConvertError

时间:2018-03-12 09:15:21

标签: delphi indy

我正在尝试阅读和处理由Thunderebird创建的电子邮件文件。我正在使用TIdMessage。它适用于绝大多数电子邮件,但有日期问题的电子邮件除外。

这是我的代码:

procedure TForm1.ButtonTestClick(Sender: TObject);
const
  CRLF = #13#10;
var
  IndyStringList: TStringList;
  IndyStream: TMemoryStream;
  IdMessage1: TIdMessage;
begin                      
  IdMessage1 := TIdMessage.Create(nil);
  s1 := 'C:\Temp\MboxTest4.txt'; //  shortened problem file

  IndyStringList := TStringList.Create;
  IndyStream := TMemoryStream.Create;
  IndyStringList.LoadFromFile(s1);
  IndyStringList.Add(CRLF + '.' + CRLF);
  IndyStringList.SaveToStream(IndyStream);
  IndyStream.Position := 0;
  try
    IdMessage1.LoadFromStream(IndyStream);
  except
    on E: EConvertError do
      ShowMessage(E.ClassName + '  ' + E.Message);
    on E : Exception do
      ShowMessage(E.ClassName+' error raised, with message : ' + E.Message);
  end;
end;

当我使用包含错误Date的文件运行此文件时,EConvertErrorException处理程序不会执行,程序会继续执行,就好像没有错误一样。

这是电子邮件:

From - Mon Jan 1 00:00:00 1965
X-Persona: <support@LondonDatabases>
Received: from yass.news.co.uk [194.129.35.178] by londondatabases.com
  (SMTPD32-6.06) id A3FA150060; Thu, 29 Aug 2002 10:47:22 -0400
From: Sunday Times Enterprise Network <01582485-001069-1644@yass.news.co.uk>
To: support@londondatabases.com
Date: Thu, 29 August 2002 15:40:46 +0100 (BST)
Subject: The Sunday Times Enterprise Network
Mime-Version: 1.0
Content-Type: text/html; charset=windows-1252
Content-Disposition: inline
User-Agent: YASS
Message-Id: <200208291047574.SM00940@yass.news.co.uk>
X-RCPT-TO: <support@londondatabases.com>
X-UIDL: 313625295
Status: U
X-Mozilla-Status: 8000
X-Mozilla-Status2: 00000000
Content-transfer-encoding: 8bit


 <HTML>

</html>

1 个答案:

答案 0 :(得分:4)

您不应该使用TStringList按照您的方式加载电子邮件文件(并且您不应该CRLF使用TStringList.Add()。没有理由手动将CRLF+'.'+CRLF序列注入电子邮件数据(除非您使用的是非常旧版本的Indy,但尚未在内部处理)。您应该使用TIdMessage.LoadFromFile()方法:

procedure TForm1.ButtonTestClick(Sender: TObject);
var
  IdMessage1: TIdMessage;
begin                      
  try
    IdMessage1 := TIdMessage.Create(nil);
    try
      IdMessage1.LoadFromFile('C:\Temp\MboxTest4.txt');
    finally
      IdMessage1.Free;
    end;
  except
    on E : Exception do
      ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
  end;
end;

或者,TIdMessageHelper.LoadFromFile()方法,如果电子邮件的行没有以点透明格式转义(有关详细信息,请参阅New TIdMessage helper):

uses
  ..., IdMessageHelper;

procedure TForm1.ButtonTestClick(Sender: TObject);
var
  IdMessage1: TIdMessage;
begin                      
  try
    IdMessage1 := TIdMessage.Create(nil);
    try
      // if using D2006+
      IdMessage1.LoadFromFile('C:\Temp\MboxTest4.txt', False, False);

      // if using pre-D2006
      TIdMessageHelper_LoadFromFile(IdMessage1, 'C:\Temp\MboxTest4.txt', False, False);
    finally
      IdMessage1.Free;
    end;
  except
    on E : Exception do
      ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
  end;
end;

无论哪种方式,您的代码未捕获日期转换错误的原因是因为Indy在内部捕获了异常并将TIdMessage.Date属性设置为0.0。代码中没有引发异常,所以只有在IDE的调试器中运行代码时才能看到它。

电子邮件的Date标头无法解析的原因是因为RFC 822 Section 5的规则格式不正确。 August应该是Aug,然后它会正确解析:

Date: Thu, 29 Aug 2002 15:40:46 +0100 (BST)

但是,Indy确实考虑了RFC 822不允许的几种替代语言拼写,但它没有处理完整的月份名称。所以我刚刚更新了Indy以支持解析其他拼写,现在你的原始“格式错误”Date将无错误地解析。