Throwing a Win32Exception

大憨熊 提交于 2019-12-03 01:37:07

This isn't really specific to Win32 exceptions; the question is, when should two different error cases be identified by two different Exception-derived types, and when should they throw the same type with different values stored inside it?

Unfortunately this is impossible to answer without knowing in advance all the situations your code will be called in. :) This is the problem with only being able to filter exceptions by type. Broadly speaking, if you have a strong feeling that it would be useful to treat two error cases differently, throw different types.

Otherwise, it is frequently the case that the string returned by Exception.Message just needs to be logged or displayed to the user.

If there is additional information, wrap the Win32Exception with something more high-level of your own. For example, you're trying to do something to a file, and the user you're running under doesn't have permission to do it. Catch the Win32Exception, wrap it in an exception class of your own, whose message gives the filename and the operation being attempted, followed by the inner exception's message.

My view has always been that the appropriate way to handle this depends on the target audience and how your class is going to be used.

If the caller of your class/method is going to realize that they are calling into Win32 in one form or another, I would use option 1) you have specified. This seems the most "clear" to me. (However, if this is the case, I'd name your class in a manner that makes it clear that the Win32 API is going to be used directly). That being said, there are exceptions in the BCL that actually subclass Win32Exception to be more clear, instead of just wrapping it. For example, SocketException derives from Win32Exception. I've never personally used that approach, but it does seem like a potentially clean way to handle this.

If the caller of your class is going to have no idea that you're calling into the Win32 API directly, I would handle the exception, and use a custom, more descriptive exception you define. For example, if I'm using your class, and there's no indication that you're using the Win32 api (since you're using it internally for some specific, non-obvious reason), I would have no reason to suspect that I may need to handle a Win32Exception. You could always document this, but it seems more reasonable to me to trap it and give an exception that would have more meaning in your specific business context. In this case, I might wrap the initial Win32Exception as an inner exception (ie: your case 4), but depending on what caused the internal exception, I might not.

Also, there are many times when a Win32Exception would be thrown from a native call, but there are other exceptions in the BCL that are more relevant. This is the case when you're calling into a native API that isn't wrapped, but there are similar functions that ARE wrapped in the BCL. In that case, I would probably trap the exception, make sure that it is what I'm expecting, but then throw the standard, BCL exception in its place. A good example of this would be to use SecurityException instead of throwing a Win32Exception.

In general, though, I would avoid option 2 and 3 you listed.

Option two throws a general Exception type - I would pretty much recommend avoiding that entirely. It seems unreasonable to wrap a specific exception into a more generalized one.

Option three seems redundant - There's really no advantage over Option 1.

Personally I would do #2 or #4...Preferably #4. Wrap Win32Exception inside your exception which is context sensitive. Like this:

void ReadFile()
{
    if (!WinApi.NativeFunction(param1, param2, param3))
        throw MyReadFileException("Couldn't read file", new Win32Exception());
}

This way if somebody catches the exception, they will have a pretty good idea where the problem occurred. I wouldn't do #1 because it requires the catch to interpret your text error message. And #3 doesn't really give any additional information.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!