2011-03-25 178 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