I am building an error handling for my rest application which uses RestSharp (Version 108.0.2) for the communication.
Lets say the server accepts http-requests on port 6543 and https-requests on port 3456.
When I now use http://myServer:3456 (which generates an error like expected) I get a TaskCanceledException
and the CancellationToken.IsCancellationRequested
is true
, so it looks like the user set the CancellationToken
to true
, but he did not.
So why is it this way and can I get a better error description which is more explaining for non-programmers or at least get a difference between manual cancellation and wrong protocol, so I can translate this to the user?
For clarification I initialize the Client this way:
RestClientOptions options = new RestClientOptions()
{
BaseUrl = new Uri(serviceUrl),
PreAuthenticate = false,
Timeout = cTimeout,
UseDefaultCredentials = globalSettings.AuthMechanism != AuthMechanism.Basic,
UserAgent = $"{Assembly.GetExecutingAssembly().GetName().Name}/{Assembly.GetExecutingAssembly().GetName().Version}"
};
RestClient = new RestClient(options);
So there is no cancellation token set on my side explicitly. Not even in the requests:
RestRequest request = new RestRequest($"{GlobalSettings.ApiSystemUrl}/info", Method.Get);
RestResponse result = await mRestClient.ExecuteAsync(request);
This is the raw result (in JSON) I get:
{
"Request":
{
"AlwaysMultipartFormData": false,
"MultipartFormQuoteParameters": false,
"FormBoundary": null,
"Parameters": [],
"Files": [],
"Method": 0,
"Timeout": 0,
"Resource": "/api/v1/info",
"RequestFormat": 0,
"RootElement": null,
"OnBeforeDeserialization": null,
"OnBeforeRequest": null,
"OnAfterRequest": null,
"Attempts": 1,
"CompletionOption": 0,
"ResponseWriter": null,
"AdvancedResponseWriter": null
},
"ContentType": null,
"ContentLength": null,
"ContentEncoding": [],
"Content": null,
"StatusCode": 0,
"IsSuccessful": false,
"StatusDescription": null,
"RawBytes": null,
"ResponseUri": null,
"Server": null,
"Cookies": null,
"Headers": null,
"ContentHeaders": null,
"ResponseStatus": 4,
"ErrorMessage": "Eine Aufgabe wurde abgebrochen.",
"ErrorException":
{
"ClassName": "System.Threading.Tasks.TaskCanceledException",
"Message": "Eine Aufgabe wurde abgebrochen.",
"Data": null,
"InnerException": null,
"HelpURL": null,
"StackTraceString": " bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n bei RestSharp.RestClient.<ExecuteInternal>d__1.MoveNext()",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": "8\nThrowForNonSuccess\nmscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\nSystem.Runtime.CompilerServices.TaskAwaiter\nVoid ThrowForNonSuccess(System.Threading.Tasks.Task)",
"HResult": -2146233029,
"Source": "mscorlib",
"WatsonBuckets": null
},
"Version": null,
"RootElement": null
}
Exception messages are server side settings in German that I now didn't translate, but as you can see, there is no InnerException or the like on my side.
Oh and I get this information like this:
if (!result.IsSuccessful)
....
if (result.ErrorException != null)
{
if (result.ErrorException is TaskCanceledException cancel)
{
if (cancel.CancellationToken.IsCancellationRequested)
{
errorDescription += " " + RestClientStrings.Error_CanceledByUser;
}
else
{
errorDescription += " " + RestClientStrings.Error_CanceledByTimeout;
}
}
}