I want to re-try execution of code block if error code = 100 and if all re-try fails I want to print the message "Operation failed after 3 times" for this case only.
I have below Polly policy defined,
var retryPolicy = Policy
.Handle<Exception>(ex =>
{
var errorMessage = ex.InnerException?.Message;
if (errorMessage == null) return false;
try
{
dynamic error = JsonConvert.DeserializeObject(errorMessage);
if (error != null && error.errorCode == 100)
{
Console.WriteLine("Try to run again...");
return true;
}
Console.WriteLine("Error occurred: " ex.Message);
return false;
}
catch (Exception)
{
Console.WriteLine("Exception Error occurred: " ex.Message);
return false;
}
})
.WaitAndRetryAsync(2, _ => TimeSpan.FromSeconds(10));
And below is the code for policy execution,
try
{
var myClass = new MyClass();
await retryPolicy.ExecuteAsync(async () => await myClass.Get());
}
catch (Exception)
{
Console.WriteLine("Operation failed after 3 times");
}
For below code everything perfect and I am getting desired result as well,
Try to run again...
Try to run again...
Try to run again...
Operation failed after 3 times
public async Task Get()
{
await Task.Delay(1);
throw new Exception("message", new Exception("{\"message\":\"inner exception\",\"errorCode\":\"100\"}"));
}
But when I am execution below code ( no error code = 100), then my re-try not happening but the message "Operation failed after 3 times" is also printing in console. What's the reason for it and how to avoid it?
Exception Error occurred: message
Operation failed after 3 times
public async Task Get()
{
await Task.Delay(1);
throw new Exception("message", new Exception("hey you"));
}
CodePudding user response:
In general it's not good, to have a try-catch-block in an Exception handling. In your case it's generated because of your JsonConvert, but do you really need that?
I would suggest, to throw an Exception of type Win32Exception
, because here you can define an error code. Like this
throw new Exception("message", new System.ComponentModel.Win32Exception(100));
With that you don't need to do a Json-Deserialzation and you got no "second" try-catch-block.
"Operation failed after 3 times" is printed on every exception, says also on exceptions without an inner one or error code == 100. To fix that, you can now do something like
try
{
var myClass = new MyClass();
await retryPolicy.ExecuteAsync(async () => await myClass.Get());
}
catch (Exception ex)
{
bool innerIsWin32 = ex.InnerException is System.ComponentModel.Win32Exception;
if (innerIsWin32)
{
var w32ex = (Win32Exception)ex.InnerException
if (w32ex.ErrorCode == 100)
{
Console.WriteLine("Operation failed after 3 times");
}
}
}
Starting with C# 6, when can be used in a catch statement to specify a condition that must be true for the handler for a specific exception to execute.
catch (Win32Exception ex) when (ex.InnerException is Win32Exception) {
var w32ex = (Win32Exception)ex.InnerException;
var code = w32ex.ErrorCode;
if (code == 100)
{
Console.WriteLine("Operation failed after 3 times");
}
}