如何在C#中更改异常对象的Message
?
奖金闲聊
Exception
的Message
属性是只读的
public virtual string Message { get; }
附加阅读
同样的问题,在PHP中,答案是“你不能”,但给出了一个变通方法:
然而,您可以确定它的类名和代码,并抛出一个新的类,具有相同的代码,但具有不同的消息。
如何确定异常的类名,并在C#中抛出同一个类的新类,但使用不同的消息?
例如:
catch (Exception e)
{
Exception e2 = Activator.CreateInstance(e.GetType());
throw e2;
}
由于异常的Message
属性为只读和.NET,因此不起作用。请参阅原始问题。
更新
我尝试捕获我期望的每一种类型的异常:
try
{
reader.Read();
}
catch (OleDbException e)
{
throw new OleDbException(e, sql);
}
catch (SqlException e)
{
throw new SqlException (e, sql);
}
catch (IBM.DbException e)
{
throw new IBM.DbException(e, sql);
}
catch (OdbcException e)
{
throw new OdbcException (e, sql);
}
catch (OracleException e)
{
throw new OracleException (e, sql);
}
除了现在我的代码强制依赖于不会出现在每个解决方案中的程序集之外。
而且,现在异常似乎来自我的代码,而不是抛出它的那行;我丢失了异常的位置信息
发布于 2012-11-01 07:34:46
我在a news site链接的a blog post中找到了解决方案
catch (Exception e)
{
Exception e2 = (Exception)Activator.CreateInstance(e.GetType(), message, e);
throw e2;
}
它并不完美(您丢失了堆栈跟踪);但这就是.NET的本质。
发布于 2012-02-18 03:32:14
您将创建一个包含新消息的新Exception
(或者更好的特定于子类型)(并将原始异常作为InnerException
传递)。
例如:
throw new MyExceptionType("Some interesting message", originalException);
注意:如果你真的想使用Activator.CreateInstance
,你可以使用可以传递参数的重载,但是不能依赖不同的异常派生类型来拥有(message, innerException)
的构造函数重载。
发布于 2012-12-11 05:11:15
我只是想在这里插话给Ian听他的答案。如果您在blog post中使用该技术,则不会丢失堆栈。是的,您将丢失最终异常的StackTrace
成员中的堆栈,但不会因为内部异常而丢失整个堆栈。看这里:
class Program
{
static void Main(string[] args)
{
try
{
Test1();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public static void Test1()
{
try
{
Test2();
}
catch (Exception ex)
{
throw ExceptionUtil.Rethrow(ex, "caught in test1");
}
}
public static void Test2()
{
throw new Exception("test2");
}
public static class ExceptionUtil
{
public static Exception Rethrow(Exception ex, string message)
{
if (ex == null)
{
ex = new Exception("Error rethrowing exception because original exception is <null>.");
}
Exception rethrow;
try
{
rethrow = (Exception)Activator.CreateInstance(ex.GetType(), message, ex);
}
catch (Exception)
{
rethrow = new Exception(message, ex);
}
return rethrow;
}
public static Exception Rethrow(Exception ex, string message, params object[] args)
{
string formatted;
try
{
formatted = String.Format(message, args);
}
catch (Exception ex2)
{
formatted = message + "\r\n\r\nAn error occurred filling in exception message details:\r\n\r\n" + ex2;
}
return Rethrow(ex, formatted);
}
}
}
如果你接受异常的完整字符串,你会得到:
System.Exception: caught in test1 ---> System.Exception: test2
at ScratchPad2.Program.Test2() in C:\Projects\Experiments\ScratchPad2\Program.cs:line 36
at ScratchPad2.Program.Test1() in C:\Projects\Experiments\ScratchPad2\Program.cs:line 26
--- End of inner exception stack trace ---
at ScratchPad2.Program.Test1() in C:\Projects\Experiments\ScratchPad2\Program.cs:line 30
at ScratchPad2.Program.Main(String[] args) in C:\Projects\Experiments\ScratchPad2\Program.cs:line 14
所以你得到了整个堆栈,外加额外的信息
https://stackoverflow.com/questions/9334182
复制相似问题