从 ArgumentException 中获取原始错误消息
Getting the original error message out of an ArgumentException
在写.Net内部处理的classes时,我经常用ArgumentException
表示给定的数据有问题,无法处理。由于程序的性质,我放在这些例外中的文本有时与用户相关,因此它经常显示在 UI.
上
但是,我注意到 ArgumentException
专门覆盖了 Message
属性 以附加其自己的字符串以指示哪个参数导致了异常。我不希望这个额外的文本污染消息,因为实际的参数名称是内部处理信息,实际上不需要向用户显示,而且它添加了一个换行符,而且它是本地化的,这很混乱提高我在 UI 上显示的消息的格式。解决这个问题的唯一方法是不给异常提供实际参数名称,但我也不想通过删除该信息来破坏我自己的调试/日志记录。
当然,我可以使用我自己的例外 class,但是由于这些方法中有很多是用于压缩和解压缩旧 DOS 游戏中的专有文件格式,我希望这些方法都被记录下来在 wiki 上并且通常可以被其他任何人轻松使用,我更愿意保持它们的便携性并避免依赖其他外部 classes。而且,作为旁注,subclassing ArgumentException
当然会给出同样的问题。
原文出处:
public override String Message
{
get {
String s = base.Message;
if (!String.IsNullOrEmpty(m_paramName)) {
String resourceString = Environment.GetResourceString("Arg_ParamName_Name", m_paramName);
return s + Environment.NewLine + resourceString;
}
else
return s;
}
}
(from referencesource.microsoft.com)
因为这实际上覆盖了 Message
属性,似乎没有正常的方法来获取内部存储的真实消息。根据本地化差异(我给它的消息可能已经有换行符),在换行符上拆分看起来很混乱并且可能不可靠,并且为此使用反射似乎相当混乱。有没有一种干净的方法来恢复原始消息?
(出于记录原因将此与解决方案一起发布在这里,因为当我遇到这种行为时,我真的很沮丧)
因为我不想深入研究反射,所以我想出了一种获取原始数据但没有关联 class 行为的好方法,那就是将其序列化。序列化信息中的属性名称非常简单,无需 ArgumentException
getter 自行添加即可访问。
完成此任务的代码非常简单:
public static String RecoverArgExceptionMessage(ArgumentException argex)
{
if (argex == null)
return null;
SerializationInfo info = new SerializationInfo(typeof(ArgumentException), new FormatterConverter());
argex.GetObjectData(info, new StreamingContext(StreamingContextStates.Clone));
return info.GetString("Message");
}
在写.Net内部处理的classes时,我经常用ArgumentException
表示给定的数据有问题,无法处理。由于程序的性质,我放在这些例外中的文本有时与用户相关,因此它经常显示在 UI.
但是,我注意到 ArgumentException
专门覆盖了 Message
属性 以附加其自己的字符串以指示哪个参数导致了异常。我不希望这个额外的文本污染消息,因为实际的参数名称是内部处理信息,实际上不需要向用户显示,而且它添加了一个换行符,而且它是本地化的,这很混乱提高我在 UI 上显示的消息的格式。解决这个问题的唯一方法是不给异常提供实际参数名称,但我也不想通过删除该信息来破坏我自己的调试/日志记录。
当然,我可以使用我自己的例外 class,但是由于这些方法中有很多是用于压缩和解压缩旧 DOS 游戏中的专有文件格式,我希望这些方法都被记录下来在 wiki 上并且通常可以被其他任何人轻松使用,我更愿意保持它们的便携性并避免依赖其他外部 classes。而且,作为旁注,subclassing ArgumentException
当然会给出同样的问题。
原文出处:
public override String Message
{
get {
String s = base.Message;
if (!String.IsNullOrEmpty(m_paramName)) {
String resourceString = Environment.GetResourceString("Arg_ParamName_Name", m_paramName);
return s + Environment.NewLine + resourceString;
}
else
return s;
}
}
(from referencesource.microsoft.com)
因为这实际上覆盖了 Message
属性,似乎没有正常的方法来获取内部存储的真实消息。根据本地化差异(我给它的消息可能已经有换行符),在换行符上拆分看起来很混乱并且可能不可靠,并且为此使用反射似乎相当混乱。有没有一种干净的方法来恢复原始消息?
(出于记录原因将此与解决方案一起发布在这里,因为当我遇到这种行为时,我真的很沮丧)
因为我不想深入研究反射,所以我想出了一种获取原始数据但没有关联 class 行为的好方法,那就是将其序列化。序列化信息中的属性名称非常简单,无需 ArgumentException
getter 自行添加即可访问。
完成此任务的代码非常简单:
public static String RecoverArgExceptionMessage(ArgumentException argex)
{
if (argex == null)
return null;
SerializationInfo info = new SerializationInfo(typeof(ArgumentException), new FormatterConverter());
argex.GetObjectData(info, new StreamingContext(StreamingContextStates.Clone));
return info.GetString("Message");
}