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;
我一定是忽略了什么....
为什么 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;