pau*_*aul 0 f# exception-handling exception
我有一个F#异常,它没有被正确的catch块捕获.
这是相关的代码:
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
Run Code Online (Sandbox Code Playgroud)
问题是excatch块捕获ConfigFileVersionIncompatabilityException异常,它应该被第一个块捕获.
我尝试使用:? System.Exception as ex而不是只是ex它仍然表现相同.
我错过了什么吗?
[在初始帖子后1分钟编辑,删除不相关的代码.]
在反序列化期间发生异常时,该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
Run Code Online (Sandbox Code Playgroud)
该Data0属性公开了异常所携带的值(我使用它,因为在使用时无法在模式匹配中轻松访问它:?).但是,您可以match使用活动模式避免表达式的丑陋嵌套(以及通用处理程序的重复):
let (|InnerException|) (e:exn) =
e.InnerException
try // ..
with
| InnerException(ConfigFileVersionIncompatabilityException s) ->
printfn "%s" s
| _ -> // generic handler
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
204 次 |
| 最近记录: |