Is there a benefit to JUST a “throw” in a catch?

2020-06-01 03:38发布

Been having a "heated debate" with a colleague about his practice of wrapping most of his functions in a try/catch but the catch has JUST a "throw" in it e.g.

Private sub foo()
    try
        'Do something'
    catch
        throw 'And nothing else!'
    End Try
End Sub

My thought was to not even bother (assuming you don't need to do anything at this point) - the exception would bubble to the next exception handler in a parent member.

The only argument that sounded plausible was that sometimes exceptions weren't caught and your code stopped (in debug mode) with the current line highlighted in green...and that this may be something to do with multiple threads? Best practice does state "an exception handler for each thread" but mostly we work single-threaded.

The good thing may be it could be useful in debug mode to not suddenly pop out to a parent member (yes, Joel!) - you'd move to the "throw" statement and be able to examine your locals. But then your code would be "littered with try/catch/throws" (to quote another thread here)?

And what sort of overhead would be involved in adding try/catch/throws everywhere if no exception occurs (i.e. should you avoid try/catches in tight loops)?

标签: c# .net vb.net
11条回答
Melony?
2楼-- · 2020-06-01 04:10

You do not need a catch clause to catch exceptions in the Visual Studio debugger. Choose Debug > Exceptions, and select which exceptions you want to catch, all of them if necessary.

查看更多
叼着烟拽天下
3楼-- · 2020-06-01 04:10

If you catch an exception and replace it with another exception, you should typically wrap the original exception in the new one. This is usually done by passing the old exception into the new one's constructor. That way you can dig in as much as necessary to figure out what happened. The main case when you wouldn't is when you need to hide data for security reasons. In these cases, you should try to log the exception data before you clear it out.

The rationale I have seen for wrapping exceptions with new ones, rather than just letting them bubble up the stack, is that exceptions should be at the same symantic level as the methods they are coming from. If I call AuthenticateUser, I don't want to see an SQL exception. Instead, I should see some exception whose name tells me the authentication task could not be completed. If I dig into this exception's inner exceptions, I could then find the SQL exception. Personally, I am still weighing the pros and cons of doing this.

查看更多
Lonely孤独者°
4楼-- · 2020-06-01 04:11

One effect of using a catch and immediate rethrow is that any inner "Finally" blocks will run before the "Catch" occurs (which will in turn be before the exception propagates). This is relevant in two scenarios:

  1. If an exception is ultimately unhandled, it's possible that the unhandled-exception trap may quit the application without running any "finally" blocks. Doing a catch and immediate rethrow will ensure that all "finally" blocks within the catch will execute, even if the exception ends up ultimately being unhandled.
  2. It is possible for code in vb.net, and possibly other languages, to act upon an exception before any finally blocks are run. Using a "try" block with a catch-and-immediate-rethrow will cause the "finally" blocks within that catch block to run before any outer "try" blocks get their first look at the exception.

An additional caveat with catch-and-immediate-rethrow: for some reason, a catch and immediate rethrow will trash the stack trace's line number for the function call that caused the exception. I don't know why the current function's entry in the stack trace can't be left alone in that case, but it isn't. If one isn't using a .pdb file to get line-number information, this isn't an issue, but if one wants to use such information, it can be annoying.

Generally, the effects mentioned above aren't desirable, but there are occasions when one or both of the first two effects they may be useful, and the third effect tolerable. In those cases, a catch with immediate rethrow may be appropriate, though the reason for it should be documented.

查看更多
你好瞎i
5楼-- · 2020-06-01 04:15

Yes, it's handy for putting a breakpoint in the catch.

An alternate and cleaner way is to breakpoint in the constructor of the object you're throwing. You're seeing the program state at a point closer to the source of the error.

查看更多
家丑人穷心不美
6楼-- · 2020-06-01 04:16

In practice, my thought is, if you don't intend to handle the error, don't catch it.

查看更多
走好不送
7楼-- · 2020-06-01 04:21

The reason you have a lone throw inside a catch rather than throwing a new exception is because this causes the original stack trace/exception data to be preserved. And one reason you might do this is because you can now set a break-point there for debugging.

查看更多
登录 后发表回答