我们如何轻松找到代码中的哪一行导致运行时异常? [英] How can we easily find what line in the code causes a runtime exception?

查看:53
本文介绍了我们如何轻松找到代码中的哪一行导致运行时异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下分析器:

public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
{
    var throwStatement = node as ThrowStatementSyntax;

    var isObjectCreationExpression = throwStatement.Expression is ObjectCreationExpressionSyntax;
    var obj = throwStatement.Expression as ObjectCreationExpressionSyntax;

    var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;
}

SyntaxKind.ThrowStatement 作为兴趣类型.

obj 应该是 null 如果抛出的异常没有以 new Exception() 的形式声明在那里,而是表示为throw e 其中 e 是先前声明的异常.

obj should be null if the thrown exception has not been declared right there in the form new Exception() but is rather presented as throw e where e is a previously declared exception.

obj.Type 被立即调用时,这反过来会抛出一个 NullReferenceException.

This in turn will throw a NullReferenceException when obj.Type is called right after.

相关示例:

static void Method1()
{
    throw new ArgumentException();
}

static void Method2(ArgumentException e)
{
    throw e;
}

第一个 throw 将通过分析器就好了,但第二个将导致 objnull 因为它不是类型ObjectCreationExpressionSyntax.

The first throw will pass the analyzer just fine, but the second one will cause obj to be null since it is not of type ObjectCreationExpressionSyntax.

在沙盒 Visual Studio 环境中,这将显示为信息消息:

In the sandbox Visual Studio environment this will show up as an information message:

用户诊断分析器FormattingFixes.EmptyArgumentException.ArgumentExceptionAnalyzer"引发异常,消息对象引用未设置为对象的实例.".

The User Diagnostic Analyzer 'FormattingFixes.EmptyArgumentException.ArgumentExceptionAnalyzer' threw an exception with message 'Object reference not set to an instance of an object.'.

在这个简短的示例中,很容易看出问题出在哪里,但在一个不那么做作的示例中,它更难发现.行和列都是1,没有帮助.

In this short sample it's easy to tell where the problem is, but in a less contrived example it will be harder to spot. The line and column are both 1, not helpful.

在传统"编程中,您的环境会自动向您显示抛出运行时异常的位置以及该时间点的值.我可以在我的代码中的某处放置一个随机断点,每次它被击中时查看所有值并尝试从那里推断它,但是一旦节点数量远高于这 2 个,这将无法很好地扩展.

In "traditional" programming, your environment automatically shows you where the runtime exception was thrown and what the values are at that point in time. I can put a random breakpoint somewhere in my code, look at all values every time it's hit and try to deduce it from there, but this doesn't scale well once the amount of nodes goes much higher than these 2.

我们如何轻松找到代码中的哪一行导致运行时异常?

How can we easily find what line in the code causes a runtime exception?

推荐答案

所以你应该仍然可以休息一下,但如果你没有检查一些事情:

So you should have still gotten a break in, but if you didn't a few things to check:

进入调试菜单,然后选择异常.您会看到抛出"或用户未处理"列.使用 Find 查找 NullReferenceException,然后选中thrown"复选框.一旦抛出 NullReferenceException,这将导致 VS 中断.如果你想变得非常激进,你可以告诉它在所有例外情况下都中断.

Go under the Debug menu, and choose Exceptions. You'll see a column for "Thrown" or "User-unhandled". Either find NullReferenceException with Find, and check a checkbox for "thrown". That'll cause VS to break as soon as a NullReferenceException is thrown. If you want to be really aggressive, you can tell it to break on all exceptions.

如果这仍然不起作用,请转到工具 > 选项、调试、常规并清除仅我的代码".这里需要注意的是,这将破坏所有异常,包括 VS 中那些甚至不是你的错的异常.(遗憾的是,我们在很多不同的地方抛出了很多异常.)

If that's still not working, go under Tools > Options, Debugging, General and clear "just my code". The caveat here is this will break on all exceptions, including ones in parts of VS that aren't even your fault. (Sadly, we throw lots of exceptions in lots of various places.)

如果您愿意,请随时提交错误,以便我们可以让我们的消息包含堆栈跟踪和行/列,以便更容易调试.

If you want, feel free to file a bug so we can make our message include the stack trace and line/column so it's easier to debug.

既然我在这里:你的代码做到了

And since I'm here: your code did

var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;

注意语法检查——如果我编写 throw new System.ArgumentException() 会发生什么?正确的方法是获取语义模型并绑定 ObjectCreationExpression 以找出真正的类型.(如果您关心的话,这也意味着您可以在别名的情况下工作.)

Be careful with the syntax checks -- what happens if I write throw new System.ArgumentException()? The proper approach is to get the semantic model and bind the ObjectCreationExpression to figure out what the real type is. (It'll also mean you work in the case of aliases, if you care.)

这篇关于我们如何轻松找到代码中的哪一行导致运行时异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆