I have the following code:
member public this.GetData(uri: string) = async {
let! res = Async.AwaitTask(httpClient.GetAsync uri)
return res
}
When the property res.IsSuccessStatusCode
is false
I would like to throw an exception, how can I achieve this. The following code won't compile:
member public this.GetData(uri: string) = async {
let! res = Async.AwaitTask(httpClient.GetAsync uri)
match res.IsSuccessStatusCode with
| true -> return res
| false -> raise new Exception("")
}
Async void methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task method, that exception is captured and placed on 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.
When you await a Task, the first exception is re-thrown, so you can catch the specific exception type (such as InvalidOperationException). However, when you synchronously block on a Task using Task. Wait or Task. Result, all of the exceptions are wrapped in an AggregateException and thrown.
The last way to handle an error with async/await is called a higher order function. We have talked about this a couple of times now. A higher order function is a function that returns another function. The way it works is you go ahead and define all of your functions, just as if you were never to have any errors.
You certainly need to wrap new Exception(...)
in brackets, but that is not sufficient in this case - both branches of the match statement need to return a value, so you also need to insert return
:
async {
let! res = Async.AwaitTask(httpClient.GetAsync uri)
match res.IsSuccessStatusCode with
| true -> return res
| false -> return raise (new Exception(""))
}
This is actually easier to write using an if
computation which can contain body that returns unit (and throws an exception if the operation did not succeed) - and so you do not need return
in that case:
async {
let! res = Async.AwaitTask(httpClient.GetAsync uri)
if not res.IsSuccessStatusCode then
raise (new Exception(""))
return res
}
So the first part is that you need to wrap the new Exception()
with brackets to make sure that F# interprets the code correctly.
raise (new Exception(""))
or you can use either of the pipe operators
raise <| new Exception("")
new Exception |> raise
or you can change the type and use failwith
failwith "some message"
Secondly, you need to return from both branches, so prefix raise
with return
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