В F # TaskBuilder task
я пытаюсь перехватить исключение и повторно выдать его как завернутое исключение:
open System.Threading.Tasks
open FSharp.Control.Tasks.V2
exception FakeDapperException of int
exception FakePersistenceException of string * exn
module FakeDapper =
let executeWrongQueryAsync (sql: string) =
task {
raise (FakeDapperException(0))
return 42
}
module FakePersistenceLayer =
let doSomeImportantDbRelatedStuffAsync (sql: string) =
task {
try
return! FakeDapper.executeWrongQueryAsync sql
with e ->
FakePersistenceException(sql, e) |> raise
return Unchecked.defaultof<int>
}
module Task =
let GetResult (task: Task<'T>) =
task.GetAwaiter().GetResult()
[<EntryPoint>]
let main _ =
let result =
FakePersistenceLayer.doSomeImportantDbRelatedStuffAsync "this is some pretty sql stuff"
|> Task.GetResult
0
Приведенный выше код работает, как и ожидалось, однако, когда я впервые реализовал, я хотел иметь что-то вроде ниже:
let doSomeImportantDbRelatedStuffAsync (sql: string) =
task {
try
return! FakeDapper.executeWrongQueryAsync sql
with e ->
FakePersistenceException(sql, e) |> raise
}
, который не может быть скомпилирован:
Program.fs(23, 17): [FS0001] Type mismatch. Expecting a 'FSharp.Control.Tasks.TaskBuilder.Step<int>' but given a 'FSharp.Control.Tasks.TaskBuilder.Step<unit>'.
The type 'int' does not match the type 'unit'
Это связано с тем, как работает task
CE, но мне интересно, есть ли способ не возвращать бесполезное значение (например, return Unchecked.defaultof<int>
), чтобы компилятор не кричал на меня.