如何解决当响应代码为 300 或更高时,TRestRequest.Execute 退出线程
我需要检查 RestResponse
中的特定状态代码,但是当状态代码不是 200 时,RestRequest.Execute
似乎会生成 EHTTPProtocolException
。
我在理解 EHTTPProtocolException
为何被加注时遇到了一些麻烦。我该如何忽略或压制它?我确实检查过它是否只是调试器,但即使在发布版本和独立运行时,代码也会在执行时停止。
我的代码如下:
procedure TdmWebsockets.GetRustMapURL(const Connection: TsgcWSConnection; const Data: string);
begin
var jdata := TJSONObject.ParseJSONValue(Data);
var restClient := TRESTClient.Create(Self);
var restResponse := TRESTResponse.Create(Self);
var restRequest := TRESTRequest.Create(Self);
try
var isStaging := jdata.GetValue<Boolean>('data.staging');
var isBarren := jdata.GetValue<Boolean>('data.barren');
var seed := jdata.GetValue<Int32>('data.seed');
var size := jdata.GetValue<Int32>('data.size');
restRequest.Client := restClient;
restRequest.Response := restResponse;
restClient.BaseURL := 'https://rustmaps.com/api/v2/maps/' + seed.ToString + '/' + size.ToString;
restClient.RaiseExceptionOn500 := False;
restRequest.AddParameter('staging',BoolToStr(isStaging,True));
restRequest.AddParameter('barren',BoolToStr(isBarren,True));
restRequest.Params.AddHeader('X-API-Key','REDACTED');
restRequest.Method := TRESTRequestMethod.rmPOST;
Writeln('before');
restRequest.Execute;
Writeln('after');
var Writer: TJsonTextWriter;
var StringWriter: TStringWriter;
try
StringWriter := TStringWriter.Create();
Writer := TJsonTextWriter.Create(StringWriter);
Writer.Formatting := TJsonFormatting.Indented;
Writer.WriteStartObject;
/////////////////////////////////////////////
Writer.WritePropertyName('command');
Writer.WriteValue(COMMAND_GETMAP);
/////////////////////////////////////////////
if restResponse.Status.SuccessOK_200 or restResponse.Status.ClientErrorDuplicate_409 then
begin
Writeln('200 ok');
Writer.WritePropertyName('success');
Writer.WriteValue(True);
/////////////////////////////////////////////
var mapID := restResponse.JSONValue.GetValue<string>('mapId');
Writer.WritePropertyName('mapID');
Writer.WriteValue(mapID);
/////////////////////////////////////////////
end
else if restResponse.Status.ClientErrorBadRequest_400 then
begin
Writeln('400 ok');
/////////////////////////////////////////////
Writer.WritePropertyName('success');
Writer.WriteValue(False);
/////////////////////////////////////////////
var reason := restResponse.JSONValue.GetValue<string>('reason');
Writer.WritePropertyName('reason');
Writer.WriteValue(reason);
/////////////////////////////////////////////
end;
Writer.WriteEndObject;
Writeln(StringWriter.ToString);
Connection.WriteData(StringWriter.ToString);
finally
StringWriter.Free;
Writer.Free;
end;
finally
restRequest.Free;
restResponse.Free;
restClient.Free;
jdata.Free;
end;
end;
编辑:
单击异常窗口上的“中断”按钮时,它会将我带到 Execute
中的 Rest.HttpClient
方法,尽管它没有被添加到用途中。单步执行它表明它在 Rest.HttpClient
而不是 Rest.Client
中执行。
当我尝试使用 try .. except
时,我需要 Rest.HttpClient
来获取异常类型 EHTTPProtocolException
。使用 try .. except
时它仍然抛出异常。我知道调试器仍然会捕获它,但代码永远不会在 try .. except
中运行,只是在异常发生后停止。
解决方法
IF 异常将 TRestRequest.Execute()
转义到您的代码中,然后用 try..except
捕获它。 EHTTPProtocolException
有一个 ErrorCode
属性,您可以在需要时查看。
try..except
根本不会阻止引发异常。调试器仍将显示引发的异常,除非您将调试器配置为忽略它。但是您的代码将能够捕获异常并根据需要对其进行处理。如果调试器因异常而中断,只需按 IDE 上的“运行”按钮或键盘上的 F9 继续执行,异常将被传递到您的程序中最近的匹配异常处理程序。代码。
例如:
try
restRequest.Execute;
except
// swallow ALL exceptions...
end;
继续前进,无需更新 uses
子句 - 除非您希望代码忽略非 EHTTPProtocolException
异常并让它们向上传播调用堆栈(如您应该的那样),在在这种情况下,您可以改用它:
uses
...,REST.HttpClient;
try
restRequest.Execute;
except
on E: Exception do begin
if not (E is EHTTPProtocolException) then begin
// DON'T swallow unknown non-HTTP errors...
raise;
end;
// swallow HTTP errors and let subsequent code check the status...
end;
end;
或者:
uses
...,REST.HttpClient;
try
restRequest.Execute;
except
on E: EHTTPProtocolException do begin
// swallow HTTP errors and let subsequent code check the status...
end;
on E: Exception do begin
// DON'T swallow unknown non-HTTP errors...
raise;
end;
end;
或者:
uses
...,REST.HttpClient;
try
restRequest.Execute;
except
on E: EHTTPProtocolException do;
// swallow only HTTP errors and let subsequent code check the status...
end;
但是,如果异常没有将 TRestRequest.Execute()
转义到您的代码中,那么这个问题就没有实际意义了。异常将在 Execute()
内处理,您的代码中根本不需要 try..except
。如果您不想在调试代码时看到异常,那么只需 configure the debugger to ignore EHTTPProtocolException
并继续。
我误解了问题所在,并专注于抛出的 HTTPException 而不是真正的问题。似乎因为我的应用程序是一个控制台应用程序并且 NotifyEvent 对于 sgcWebsockets 中的线程来说是 noSync 线程最终在每次调用 TCustomRESTClient.HandleEvent
时退出。在这种情况下,它被调用并实际执行,因为 restRequest.SynchronizedEvents
默认设置为 true 但应该为 false。
所以解决方案很简单:
restRequest.SynchronizedEvents := False;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。