问题
I'm working on F# project and I wonder what is the best practice to return domain error using Result
type in F#. There are several ways of doing it which I consider:
Inherited exceptions
type DomainException(message) =
inherit Exception(message)
type ItemNotFoundException(item) =
inherit DomainException(sprintf "Item %s is not found" item)
let findItem item =
match item with
| Some x -> Ok x
| None -> Error(new ItemNotFoundException("someitem"))
Custom record type
type DomainError =
{ Name : string
Message : string }
let findItem item =
match item with
| Some x -> Ok x
| None ->
Error({ Name = "ItemNotFound"
Message = "Item someitem is not found" })
Discriminated union of record type
type DomainErrorTypes =
| ItemNotFoundError of DomainError
| ItemInvalidFormat of DomainError
let findItem item =
match item with
| Some x -> Ok x
| None ->
{ Name = "ItemNotFound"
Message = "Item someitem is not found" }
|> ItemNotFoundError
|> Error
So which way is more idiomatic and convenient to use? I also will be happy to see better options.
回答1:
Typically it would be a discriminated union. Every error requires different details to accompany the message. For instance:
type DomainErrorTypes =
| ItemNotFound of ItemId
| FileNotFound of string
| InvalidFormat of format
| IncompatibleItems of Item * Item
| SQLError of code:int * message:string
| ...
You can also capture some exceptions (not necessarily all):
| ...
| Exception of exn
来源:https://stackoverflow.com/questions/53650500/what-is-the-most-idiomatic-way-of-representing-errors-in-f