First off, let's format it...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
exception Error1 of string


let foo1 ()=
    let x=3
    if(x.Equals(3))then
        raise(Error1 ("bbb"))
    else
        true


let foo2 ()=
    try
        foo1()
    with
    |Error1(str) -> raise(Error1 (str))


let foo3 ()=
    try
        foo2()
    with
    |Error1(str)->printfn "%s" str; // Error "Type mismatch..", as described in OP


foo3()

Yes, you are propagating and handling the exceptions correctly, from foo1 up through foo2 to foo3.

The problem is that type inference has given foo3 the type unit -> bool. This is what you want, but you must return a bool from all paths (or else raise an exception), and your exception handler does not return a bool (in fact, it is of type unit).

You can fix it with this, in foo3...

|Error1(str)->printfn "%s" str; false // return a bool from the handler

Here's the same code, with some diagnostics so you can see the exceptions being handled...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
exception Error1 of string

let foo1 ()=
    let x=3
    if(x.Equals(3))then
        printfn "raise in foo1"
        raise(Error1 ("bbb"))
    else
        true

let foo2 ()=
    try
        foo1()
    with
    |Error1(str) -> printfn "Caught %s in foo2, reraise" str; raise(Error1 (str))

let foo3 ()=
    try
        foo2()
    with
    |Error1(str)-> printfn "Caught %s in foo3. Stop here" str; false

foo3()

btw, to format F# code, just press the F# button above the post editor, and insert your code between the tags provided, or enter

1
<code lang=fsharp>...f# code...

</code>

By on 12/29/2009 6:07 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper