tags:

views:

138

answers:

3

I have a simple custom exception defined like like the following but I don't like having to use the Throw function and I really don't like having both Throw and a Throw2 functions. Is there a more elegant way of doing this? Is there a way of throwing MyError or Error directly without the intermediate function?

#light

module Utilities.MyException

type MyError(code : int, msg : string) =
    member e.Msg  = msg
    member e.Code = code
    new (msg : string) = MyError(0, msg)

exception Error of MyError

let public Throw (msg : string) =
    let err = new MyError(msg)
    raise (Error err)

let public Throw2 (code : int) (msg : string) =
    let err = new MyError(code, msg)
    raise (Error err)

I'm using it like the following but I'd like to use one of the variants that didn't work

Throw(System.String.Format("Could not parse boolean value '{0}'", key))

//The string isn't of the correct type for Error
//raise(Error(System.String.Format("Could not parse boolean value '{0}'", key)))

//MyError isn't compatible with System.Exception
//raise(MyError(System.String.Format("Could not parse boolean value '{0}'", key)))
+4  A: 

Just ignore exception construct and define the exception class - that is, one deriving from System.Exception - directly, as in C#:

type MyError(code : int, msg : string) =
    inherit Exception(msg)
    member e.Code = code
    new (msg : string) = MyError(0, msg)

raise(MyError("Foo"))
raise(MyError("Foo", 1))

Note that I removed Msg member, because Exception has an equivalent Message property already.

Pavel Minaev
I knew it had to be this easy. Thanks!
telesphore4
+1  A: 

I am unclear exactly what you are after, but how does this work for you?

exception Error of int * string
let ErrorC(s) = Error(0,s)

let F() =
    try
        let key = true
        raise <| Error(42, System.String.Format("Could not parse '{0}'", key))
        raise <| ErrorC(System.String.Format("Could not parse '{0}'", key))
    with Error(code, msg) ->
        printfn "%d: %s" code msg
Brian
Ah... the star notation will come in handy. I also like the use of the reverse pipe.
telesphore4
+1  A: 

How about redefining MyError as a record and using the record syntax to record the error, e.g.:-

type MyError =
    { Msg:  string;
      Code: int } 

exception Error of MyError

raise <| Error { Msg  = ( sprintf "Could not parse boolean value '%b'" key );
                 Code = code }
kronoz
OK, but how complicated would it be to have a variant that only had the message, or defaulted the code field to 0?
telesphore4
Simply define a function?
kronoz