TNetHTTPClient OnRequestError 不触发

TNetHTTPClient OnRequestError does not trigger

我一定是忽略了什么....
为什么 NetHTTPClientRequestError 在这里没有被触发?

type
   TUpdateChecker = class
      private
         var FHTTP  : TNetHTTPClient;
         var FAbort : Boolean;
         procedure NetHTTPClientRequestError(const Sender: TObject; const AError: string);
      public
         constructor Create;
         destructor Destroy; override;
         function CheckNewVersion(var ANewVer: String): Boolean;
      end;

{ TUpdateChecker }

constructor TUpdateChecker.Create;
begin
   inherited;
   FHTTP := TNetHTTPClient.Create(nil);
   FHTTP.OnRequestError := NetHTTPClientRequestError;  // Error handler assigned here
   FHTTP.ConnectionTimeOut := 10000;
end;

destructor TUpdateChecker.Destroy;
begin
   FHTTP.Free;
   inherited;
end;

function TUpdateChecker.CheckNewVersion(var ANewVer: String): Boolean;
var
   lJSONStr: String;
begin
   Result := false;
   try
      lJSONStr := FHTTP.Get(cUpdateJSON + 'sdhgfy').ContentAsString;  // Add some junk to cause error
   except
      on E:Exception do   
      begin
         // We don't get at the breakpoint here  
         WriteErrorLog(TSettings.DataLocation + cErrLogFile, 'CheckNewVersion: ' + E.Message);
         Exit;
      end;
   end;

   if FAbort then Exit;  // FABort = false here

   // Rest of code removed
end;

procedure TUpdateChecker.NetHTTPClientRequestError(const Sender: TObject; const AError: string);
begin
   // We don't get at the breakpoint here, FAbort never becomes true
   ShowMessage('ERROR Sender.ClassName=' + Sender.ClassName + ' AError=' + AError);
   FAbort := true;
end;

从 FormShow 调用代码:

 lCheck := TUpdateChecker.Create;
 try
    if lCheck.CheckNewVersion(lNewVer) then
    begin
       LblNewVersion.Caption := Format(LblNewVersion.Caption,[lNewVer]);
       LblNewVersion.Visible := true;
       LblUpgrade.Visible    := true;
    end;
 finally
    lCheck.Free;
 end;

这是 Win10 上的 Win32 应用 运行。

cUpdateJSON 是我网站上 JSON 文件的有效 URL。我添加了 'sdhgfy' 垃圾来导致错误。我的注意力是捕获 'common' HTTP 状态代码,如 500、404,以及异常。

因为:

lJSONStr := FHTTP.Get(cUpdateJSON + 'sdhgfy').ContentAsString; 

执行成功。

无论 cUpdateJSON 是什么,它都指向一个向您返回数据的有效服务器,即使您附加了一些垃圾。它不会是您期望的数据,但它仍然是数据,因此不会引发错误。

您将需要验证返回的数据以确保服务器返回您所期望的。 NetHTTPClientRequestError 将仅处理指定的 URL 连接失败等情况(传输、套接字和协议级别异常)。它对另一端的服务是否能够处理您的特定请求一无所知。它成功地传递了您的请求并且服务器返回了响应。这就是它所关心的。

如果您想检查服务器响应,您可以在将其内容保存到字符串之前检查返回的 IHTTPResponse 中的 StatusCode

function TUpdateChecker.CheckNewVersion(var ANewVer: String): Boolean;
const
  HTTP_OK = 200;
var
  lResp : IHTTPResponse;
  lJSONStr: String;
begin
   Result := false;
   try
      lResp := FHTTP.Get('http://www.google.com/thiswontwork');

      // Note by OP: *if* the NetHTTPClientRequestError gets triggered
      // we have serious errors like e.g. invalid certificates
      // and lResp.StatusCode will give an AV. Therefore:
      if FAbort then Exit;

      if lResp.StatusCode <> HTTP_OK then begin
        // handle me!
      end else
        lJSONStr := lResp.ContentAsString();
   except
      on E:Exception do
      begin
        WriteErrorLog(TSettings.DataLocation + cErrLogFile,
                      'CheckNewVersion: ' + E.Message);
        Exit;
      end;
   end;

   if FAbort then Exit;  // FABort = false here

   // Rest of code removed
end;