I am working on some code to use HttpWebRequest asynchronously. If any of you have ever done this before, then you know that error handling can be a bit of a pain because if an exception is thrown in one of the callback methods, it can't be passed back to the calling code via a try/catch block.
What I want to do is handle errors by saving exceptions in my state object that gets passed to each callback method. If an exception is caught, the state object will be updated and then the http call will be aborted. The problem I have is that in my state object, I have to use an Exception property so that any type of exception can be stored. When the calling code checks the state object and "sees" an Exception, it doesn't know what type of exception it is.
Is there a way to allow my state object to hold any type of exception, but still keep the exception strongly-typed?
State Object
public class HttpPostClientAsyncModel
{
public HttpResponseSnapshot Response { get; set; }
public HttpPostClientAsyncStatus Status { get; set; }
public Exception Exception { get; set; }
public WebRequest Request { get; set; }
}
Handling Exceptions in Asynchronous Methods Returning a Task Object. If an exception is raised within an asynchronous method returning a Task object, the exception is wrapped into an instance of the AggregateException class and passed back to the calling method.
When an exception occurs in an async method that has a return type of Task or Task, the exception object is wrapped in an instance of AggregateException and attached to the Task object. If multiple exceptions are thrown, all of them are stored in the Task object.
To catch an exception that an async task throws, place the await expression in a try block, and catch the exception in a catch block. Uncomment the throw new Exception line in the example to demonstrate exception handling. The task's IsFaulted property is set to True , the task's Exception.
The HttpWebRequest class provides support for the properties and methods defined in WebRequest and for additional properties and methods that enable the user to interact directly with servers using HTTP.
The exception object is still strongly typed and retains its original field values. All you need is to check it like this:
if (asyncModel.Exception is ArgumentException)
{
// Handle argument exception here
string invalidParameter = (asyncModel.Exception as ArgumentException).ParamName;
}
else if (...)
{
}
You would normally do a very similar check with try/catch block anyway so this shouldn't be inconvenient. If you're really worried about this, just create a new thread with the sync methods and handle the exception with continuation options:
Task.Factory.StartNew(() => { DoWork(); })
.ContinueWith(t => Logger.Error("An exception occurred while processing. Check the inner exception for details", t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With