Tôi muốn thử nghiệm các công việc sau đây async (với NUnit + FsUnit):Làm thế nào để có được một stacktrace hữu ích khi thử nghiệm F # async dòng làm việc
let foo = async {
failwith "oops"
return 42
}
tôi đã viết các bài kiểm tra sau cho nó:
let [<Test>] TestFoo() =
foo
|> Async.RunSynchronously
|> should equal 42
Kể từ foo ném tôi nhận được stacktrace sau trong runner đơn vị kiểm tra:
System.Exception : oops
at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously(CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously(FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
at ExplorationTests.TestFoo() in ExplorationTests.fs: line 76
Thật không may là stacktrace nai không nói cho tôi biết nơi ngoại lệ được nêu ra. Nó dừng tại RunSynchronously.
Một nơi nào đó tôi nghe nói rằng Async.Catch kỳ diệu khôi phục stacktrace, vì vậy tôi điều chỉnh thử nghiệm của tôi:
let [<Test>] TestFooWithBetterStacktrace() =
foo
|> Async.Catch
|> Async.RunSynchronously
|> fun x -> match x with
| Choice1Of2 x -> x |> should equal 42
| Choice2Of2 ex -> raise (new System.Exception(null, ex))
Bây giờ đây là xấu xí nhưng ít nhất nó tạo ra một stacktrace hữu ích:
System.Exception : Exception of type 'System.Exception' was thrown.
----> System.Exception : oops
at Microsoft.FSharp.Core.Operators.Raise(Exception exn)
at ExplorationTests.TestFooWithBetterStacktrace() in ExplorationTests.fs: line 86
--Exception
at Microsoft.FSharp.Core.Operators.FailWith(String message)
at [email protected](Unit unitVar) in ExplorationTests.fs: line 71
at [email protected](AsyncParams`1 args)
này thời gian stacktrace cho thấy chính xác nơi lỗi xảy ra: [email protected] 71
Có cách nào để loại bỏ Async.Catch và kết hợp giữa hai lựa chọn trong khi vẫn nhận được stacktraces hữu ích? Có cách nào tốt hơn để cấu trúc các kiểm tra quy trình làm việc không đồng bộ không?
Tôi gặp sự cố tương tự và Không đồng bộ.Catch là giải pháp duy nhất tôi có thể tìm thấy –
Tôi đã gửi email cho Don Syme, người đã đề xuất nó là một hạn chế .NET cơ bản và rằng 'Async.Catch' là tùy chọn duy nhất. –
@ JohnPalmer nghe có vẻ như một câu trả lời cho tôi – mydogisbox