Exception F#未正确捕获异常
我有一个F#异常,它没有被正确的catch块捕获 以下是相关代码:Exception F#未正确捕获异常,exception,exception-handling,f#,Exception,Exception Handling,F#,我有一个F#异常,它没有被正确的catch块捕获 以下是相关代码: exception ConfigFileVersionIncompatabilityException of string [<XmlType("config")>] type Configuration() = class let thisVersion : string = "1.0" let mutable fileVersion : string = thisVersion [&
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
异常配置文件版本不兼容字符串异常
[]
类型配置()=类
让此版本:string=“1.0”
让可变文件版本:字符串=此版本
[]
成员x.FileVersion
使用get()=fileVersion
并设置v=if v此版本
然后引发(ConfigFileVersionInCompatibilityException(String.Format(“预期版本为{0},但读取版本为{1}.”,thisVersion,v)))
结束
模块过滤器文件函数=
让sampleConfigFilename=“sample.filters”
let readConfig(文件:string)=
尝试
在中使用xmlDoc=newstreamreader(文件)
设s=XmlSerializer(typeof)
s、 反序列化(xmlDoc):?>配置|>成功
具有
|ConfigFileVersionInCompatibilityException->
String.Format(“未能读取配置文件:\“{0}\”;\n给出了以下原因:\n{1}”,文件,s)
|>失败
|ex->
Format(“未能读取配置文件:\“{0}\”;\n{1}”,文件,ex)
|>失败
问题是,ex
catch块捕获了ConfigFileVersionInCompatibilityException
异常,第一个块应该捕获该异常
我试着使用:?System.Exception作为ex
而不仅仅是ex
,它的行为仍然相同
我错过什么了吗
[在首次发布后1分钟编辑以删除不相关的代码。]当反序列化过程中出现异常时,
反序列化
方法将捕获该异常并将其包装在InvalidOperationException
中。这意味着您需要聊天invalidooperationexception
,然后分析InnerException
属性以获得用户定义的异常
try // ..
with
| :? InvalidOperationException as invOp ->
match inv.InnerException with
| :? ConfigFileVersionIncompatabilityException as e ->
printfn "%s" e.Data0
| _ -> // generic handler
| e -> // generic handler
Data0
属性公开异常携带的值(我使用了它,因为在使用:?
时,您无法在模式匹配中轻松访问它)。但是,您可以使用活动模式避免match
表达式的丑陋嵌套(以及泛型处理程序的重复):
let (|InnerException|) (e:exn) =
e.InnerException
try // ..
with
| InnerException(ConfigFileVersionIncompatabilityException s) ->
printfn "%s" s
| _ -> // generic handler
当反序列化过程中发生异常时,
反序列化
方法将捕获异常并将其包装在InvalidOperationException
中。这意味着您需要聊天invalidooperationexception
,然后分析InnerException
属性以获得用户定义的异常
try // ..
with
| :? InvalidOperationException as invOp ->
match inv.InnerException with
| :? ConfigFileVersionIncompatabilityException as e ->
printfn "%s" e.Data0
| _ -> // generic handler
| e -> // generic handler
Data0
属性公开异常携带的值(我使用了它,因为在使用:?
时,您无法在模式匹配中轻松访问它)。但是,您可以使用活动模式避免match
表达式的丑陋嵌套(以及泛型处理程序的重复):
let (|InnerException|) (e:exn) =
e.InnerException
try // ..
with
| InnerException(ConfigFileVersionIncompatabilityException s) ->
printfn "%s" s
| _ -> // generic handler
它起作用了!我真的应该从它显示的消息中发现异常被包装在另一个异常中。好吧。我必须更多地研究活动模式——虽然我在Haskell工作过一段时间,但我对F#还是相当陌生。看来你的39.2k代表是当之无愧的,非常感谢!它起作用了!我真的应该从它显示的消息中发现异常被包装在另一个异常中。好吧。我必须更多地研究活动模式——虽然我在Haskell工作过一段时间,但我对F#还是相当陌生。看来你的39.2k代表是当之无愧的,非常感谢!