区分不同类型的 EIdDnsResolverError
Distinguish EIdDnsResolverError of different kind
我正在使用 TIdDNSResolver
扫描本地网络中的 DNS 服务器,因此 DNS 请求的结果并不重要。我检查是否有 DNS 服务器。
该应用也不应依赖于所请求的 DNS 记录是否存在,因此它请求的不是现有主机,而是明知不存在的名称。
在这种情况下,引发了 EIdDnsResolverError
类型的异常。
此异常可能伴随以下错误文本:
- TimedOut - 这意味着 DNS 服务器没有及时响应,我们应该假设它不存在。
- DNS 服务器报告查询名称错误 - DNS 服务器存在
- DNS 服务器报告查询服务器错误 - DNS 服务器存在
我不喜欢通过错误文本来区分这些错误。还有其他区分方式吗?
function TDNSChecker.CheckServer(host: string): Boolean;
var
dr: TIdDNSResolver;
begin
Result := False;
try
dr := TIdDNSResolver.Create(nil);
try
dr.Host := host;
dr.QueryType := [qtA];
dr.WaitingTime := 1000;
dr.Resolve('feufgzrfapoduiuzgfuzfsufseuszfu'); //knowingly non-existent name
Result := True;
finally
_finished := True;
dr.Free();
end;
except
on ex: EIdDnsResolverError do
if ex.Message <> 'TimedOut' then begin
if (ex.Message = 'DNS Server Reports Query Name Error') or (ex.Message = 'DNS Server Reports Query Server Error') then
Result := True
else
Log(host + ' - ' + ex.ClassName + ': ' + ex.Message.Replace(#13#10, ' '));
end;
on ex: Exception do;
end;
end;
不幸的是,TIdDNSResolver
目前不对不同的 DNS 错误使用不同的异常 class 类型,它只使用 EIdDnsResolverError
。我在 Indy 的问题跟踪器中有 opened a ticket,可能会在未来的版本中添加更多错误 classes。
因此,与此同时,要区分 DNS 错误,您必须查看异常 Message
属性。可能的错误消息作为资源字符串存储在 IdResourceStringsProtocols
单元中(大约有 21 个与 DNS 错误相关的字符串)。请注意,其中一些是格式化字符串,因此按原样进行简单比较是行不通的,您将不得不使用类似 TextStartsWith()
或类似的东西来忽略任何格式化部分。
另一方面,如果您收到 EIdDnsResolverError
异常,通常 意味着您收到了来自 DNS 服务器的响应。您不需要区分每个可能的 Indy DNS 错误就可以知道 DNS 服务器的存在。只有少数 EIdDnsResolverError
错误与连接本身有关,例如 RSDNSTimeout
、RSTunnelConnectToMasterFailed
等,而不是与 DNS 消息传递的内容有关。
如果您使用的 Delphi 版本具有 Exception.InnerException
属性 可用,则 InnerException
可以设置为 EIdConnectTimeout
或 EIdConnectException
当 TIdDNSResolver
使用 TCP(仅当 qtAXFR
或 qtIXFR
出现在 QueryType
中时)而不是 UDP。 InnerException
也有可能是 EIdNotEnoughData
,但那是消息传递错误,而不是连接错误。
在您的示例中,将使用 UDP,因此我认为除了 RSDNSTimeout
之外的任何 EIdDNSResolverError
错误都表明存在 DNS 服务器。
我正在使用 TIdDNSResolver
扫描本地网络中的 DNS 服务器,因此 DNS 请求的结果并不重要。我检查是否有 DNS 服务器。
该应用也不应依赖于所请求的 DNS 记录是否存在,因此它请求的不是现有主机,而是明知不存在的名称。
在这种情况下,引发了 EIdDnsResolverError
类型的异常。
此异常可能伴随以下错误文本:
- TimedOut - 这意味着 DNS 服务器没有及时响应,我们应该假设它不存在。
- DNS 服务器报告查询名称错误 - DNS 服务器存在
- DNS 服务器报告查询服务器错误 - DNS 服务器存在
我不喜欢通过错误文本来区分这些错误。还有其他区分方式吗?
function TDNSChecker.CheckServer(host: string): Boolean;
var
dr: TIdDNSResolver;
begin
Result := False;
try
dr := TIdDNSResolver.Create(nil);
try
dr.Host := host;
dr.QueryType := [qtA];
dr.WaitingTime := 1000;
dr.Resolve('feufgzrfapoduiuzgfuzfsufseuszfu'); //knowingly non-existent name
Result := True;
finally
_finished := True;
dr.Free();
end;
except
on ex: EIdDnsResolverError do
if ex.Message <> 'TimedOut' then begin
if (ex.Message = 'DNS Server Reports Query Name Error') or (ex.Message = 'DNS Server Reports Query Server Error') then
Result := True
else
Log(host + ' - ' + ex.ClassName + ': ' + ex.Message.Replace(#13#10, ' '));
end;
on ex: Exception do;
end;
end;
不幸的是,TIdDNSResolver
目前不对不同的 DNS 错误使用不同的异常 class 类型,它只使用 EIdDnsResolverError
。我在 Indy 的问题跟踪器中有 opened a ticket,可能会在未来的版本中添加更多错误 classes。
因此,与此同时,要区分 DNS 错误,您必须查看异常 Message
属性。可能的错误消息作为资源字符串存储在 IdResourceStringsProtocols
单元中(大约有 21 个与 DNS 错误相关的字符串)。请注意,其中一些是格式化字符串,因此按原样进行简单比较是行不通的,您将不得不使用类似 TextStartsWith()
或类似的东西来忽略任何格式化部分。
另一方面,如果您收到 EIdDnsResolverError
异常,通常 意味着您收到了来自 DNS 服务器的响应。您不需要区分每个可能的 Indy DNS 错误就可以知道 DNS 服务器的存在。只有少数 EIdDnsResolverError
错误与连接本身有关,例如 RSDNSTimeout
、RSTunnelConnectToMasterFailed
等,而不是与 DNS 消息传递的内容有关。
如果您使用的 Delphi 版本具有 Exception.InnerException
属性 可用,则 InnerException
可以设置为 EIdConnectTimeout
或 EIdConnectException
当 TIdDNSResolver
使用 TCP(仅当 qtAXFR
或 qtIXFR
出现在 QueryType
中时)而不是 UDP。 InnerException
也有可能是 EIdNotEnoughData
,但那是消息传递错误,而不是连接错误。
在您的示例中,将使用 UDP,因此我认为除了 RSDNSTimeout
之外的任何 EIdDNSResolverError
错误都表明存在 DNS 服务器。