- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我正在开发一个项目时,我心想“嗯,记录一条消息,然后用同一消息抛出一个异常,这真的很方便”。因为这可以让我保留“异常(exception)是特殊情况”的原则,但仍然确保我们记录有关系统中出现问题的详细信息。
因此产生了:
public static class LogAndThrow
{
public static void Message<TException>(string message) where TException : Exception
{
// Log message here
var constructor =
typeof(TException).GetConstructor(new[] { typeof(string) });
throw (TException)constructor.Invoke(new[] { message });
}
}
当然,这有点粗糙(我在这篇文章中将其删减了),但它确实有效。
然而,作为通过反射构建异常的人,我很恼火堆栈跟踪会被 LogAndThrow.Message() 行“污染”。
所以我开始解决这个问题:-)
我能够用一些序列化和其他技巧来替换堆栈跟踪,所有这些都非常愚蠢且暴力。但我想弄清楚这一点只是因为。
但我注意到一些奇怪的事情:
var exception = new Exception();
throw exception;
在创建该异常之后,但在抛出该异常之前,唯一设置的是消息。堆栈跟踪等都是空的。
上面等价于下面的IL:
.locals init (
[0] class [mscorlib]System.Exception exception)
nop
newobj instance void [mscorlib]System.Exception::.ctor()
stloc.0
ldloc.0
throw
在我看来,“抛出”的 IL 所做的不仅仅是获取该引用并在堆栈中遍历它。
有谁知道当到达 IL“抛出”时运行时正在对堆栈上的异常执行什么操作?
我们下面用来更改堆栈的技巧与我认为的 throw 中的“魔法”有关:
这段代码是可怕且错误的。更多的是一个科学实验,而不是任何应该永远投入生产的东西
var e = new Exception("message here");
try
{
throw e;
}
finally
{
// Get the private file _stackTraceString with reflection
field.SetValue(e, new StackTrace(1).ToString());
}
最佳答案
为什么不能修改静态方法以返回异常对象并稍后抛出。例如
// Do something
...
// Found error condition, need to throw an exception
if (error condition)
{
throw LogAndThrow.Message("Message goes here");
}
编辑:据我所知,没有办法修改堆栈跟踪。有多种方法可以在重新抛出异常时保留原始堆栈跟踪 - 请参阅此 article为了它。
另一次编辑:
只是想我会添加一些额外的信息和链接。基本上,CLR 仅在引发异常时才在异常对象中构建堆栈跟踪。这已在 MSDN 中提到过。 - 引用自 MSDN:
The common language runtime (CLR) updates the stack trace whenever an exception is thrown in application code (by using the throw keyword). If the exception was rethrown in a method that is different than the method where it was originally thrown, the stack trace contains both the location in the method where the exception was originally thrown, and the location in the method where the exception was rethrown. If the exception is thrown, and later rethrown, in the same method, the stack trace only contains the location where the exception was rethrown and does not include the location where the exception was originally thrown
这也提到了here (作者提到 CLR 在遇到托管代码中的异常时会执行堆栈遍历)。
关于一些相关的注释(但有点偏离主题),请参阅 this excellent article (带有示例代码)作者构造备用堆栈跟踪信息(基本上,他从非标准位置查找调试信息)。
关于.net - CLR 对 'throw' 做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3527020/
我有一个关于 JavaScript 语法的问题。实际上,我在自学 MEAN 堆栈教程时想出了编码(https://thinkster.io/mean-stack-tutorial#adding-aut
在我的书中它使用了这样的东西: for($ARGV[0]) { Expression && do { print "..."; last; }; ... } for 循环不完整吗?另外,do 的意义何
我已经编写了读取开关状态的代码,如果按 3 次 # 则退出。 void allkeypadTest(void) { static uint8_t modeKeyCount=0; do
因此,对于上周我必须做的作业,我必须使用 4 个 do-while 循环和 if 语句在 Java 中制作一个猜谜游戏。我无法成功完成它,类(class)已经继续,没有为我提供任何帮助。如果有人可以查
int i=1,j=0,n=10,k; do{ j+=i; i<<1; printf("%d\n",i); // printf("%d\n",12<<1); }while
此代码用于基本杂货计算器的按钮。当我按下按钮时,一个输入对话框会显示您输入商品价格的位置。我遇到的问题是我无法弄清楚如何获得 do ... while 循环以使输入对话框在输入后弹出。 我希望它始终恢
当我在循环中修改字符串或另一个变量时,它的条件是否每次都重新计算?或者在循环开始前一次 std::string a("aa"); do { a = "aaaa"; } while(a.size<10)
我刚刚写了这个,但我找不到问题。我使用代码块并编写了这个问题 error: expected 'while' before '{' token === Build finished: 1 errors
do { printf("Enter number (0-6): ", ""); scanf("%d", &Num); }while(Num >= 0 && Num 表示“超过”,<表
我有一个包含 10 个项目的 vector (为简单起见,所有项目都属于同一类,称其为“a”)。我想要做的是检查“A”不是 a) 隐藏墙壁或 b) 隐藏另一个“A”。我有一个碰撞函数可以做到这一点。
嗨,这是我的第二个问题。我有下表 |-----|-------|------|------| |._id.|..INFO.|.DONE.|.LAST.| |..1..|...A...|...N..|.
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: Why are there sometimes meaningless do/while and if/e
来自 wikibook在 F# 上有一小部分它说: What does let! do?# let! runs an async object on its own thread, then it i
我在 Real World Haskell 书中遇到了以下函数: namesMatching pat | not (isPattern pat) = do exists do
我有一个类似于下面的用例,我创建了多个图并使用 gridExtra 将它们排列到一些页面布局中,最后使用 ggsave 将其保存为 PDF : p1 % mutate(label2
当我使用具有 for 循环的嵌套 let 语句时,如果没有 (do (html5 ..)),我将无法运行内部 [:tr]。 (defpartial column-settings-layout [&
执行 vagrant up 时出现此错误: anr@anr-Lenovo-G505s ~ $ vagrant up Bringing machine 'default' up with 'virtua
# ################################################# # Subroutine to add data to the table Blas
我想创建一个检查特定日期格式的读取主机。此外,目标是检查用户输入是否正确,如果不正确,则提示应再次弹出。 当我刚接触编程时,发现了这段代码,这似乎很合适。我仍然在努力“直到” do {
我关注这个tutorial在谷歌云机器学习引擎上进行培训。我一步一步地跟着它,但是在将 ml 作业提交到云时我遇到了错误。我运行了这个命令。 sam@sam-VirtualBox:~/models/r
我是一名优秀的程序员,十分优秀!