2011-03-25 107 views
0

我有一个F#异常,它没有被捕获到正确的catch块中。F#异常未被捕获正确

下面是相关代码:

exception ConfigFileVersionIncompatabilityException of string 

[<XmlType("config")>] 
type Configuration() = class 

    let thisVersion : string = "1.0" 
    let mutable fileVersion : string = thisVersion 

    [<XmlAttribute("version")>] 
    member x.FileVersion 
     with get() = fileVersion 
     and set v = if v <> thisVersion 
        then raise (ConfigFileVersionIncompatabilityException(String.Format("Was expecting version {0} but read version {1}.", thisVersion, v))) 
end 


module FilterFileFunctions = 

    let sampleConfigFilename = "sample.filters" 

    let readConfig (file : string) = 
     try 
      use xmlDoc = new StreamReader(file) in 
       let s = XmlSerializer(typeof<Configuration>) 
       s.Deserialize(xmlDoc) :?> Configuration |> Success 
     with 
     | ConfigFileVersionIncompatabilityException(s) -> 
      String.Format("Failed to read the configuration file: \"{0}\";\nThe following reason was given:\n{1}", file, s) 
      |> Failure 
     | ex -> 
      String.Format("Failed to read the configuration file: \"{0}\";\n{1}", file, ex) 
      |> Failure 

的问题是,ex catch块捕捉ConfigFileVersionIncompatabilityException例外,它应该由第一次块被捕获。

我试图用:? System.Exception as ex而不是ex,它仍然表现相同。

我错过了什么吗?

[主编1初始后之后分钟以除去无关的代码。]

回答

6

当异常的反序列化过程发生时,Deserialize方法会抓住它,敷内部InvalidOperationException。这意味着您需要与InvalidOperationException进行沟通,然后分析InnerException属性以获取用户定义的异常。

try // .. 
with 
| :? InvalidOperationException as invOp -> 
    match inv.InnerException with 
    | :? ConfigFileVersionIncompatabilityException as e -> 
    printfn "%s" e.Data0 
    | _ -> // generic handler 
| e -> // generic handler 

Data0属性公开由异常(I使用它,因为可以不容易在图案匹配使用:?时访问它)承载的值。但是,您可以使用主动模式避免match表达丑陋嵌套(和通用处理器的重复):

let (|InnerException|) (e:exn) = 
    e.InnerException 

try // .. 
with 
| InnerException(ConfigFileVersionIncompatabilityException s) -> 
    printfn "%s" s 
| _ -> // generic handler 
+0

它的工作原理!我真的应该发现,这个异常是从它显示的消息中被包裹在另一个异常中的。呃,好吧。我将不得不更多地关注活动模式 - 尽管我在Haskell中工作过一些,但我仍然对F#很陌生。看来你的39.2k代表是当之无愧的,非常感谢! – paul 2011-03-25 18:43:58