开发者

C# try {} catch {}

hi and thanks for reading. im a newbie in programming and C# and sockets programming. in my code i try and catch problems to provide fault tolarence in my app. the following:

        catch (ArgumentNullException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (EncoderFallbackException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (SocketException 开发者_如何学Ce)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (ArgumentOutOfRangeException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (ObjectDisposedException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }

i was just wondering if i can replace this repetitive code with one single:

catch (Exception e) { handle here}

would this work?

thanks again.


No, never catch System.Exception. I feel like a broken record today, but I really can't stress this enough. You cannot handle an OutOfMemoryException or AccessViolationException, so don't catch it!

As for the example code, I have strong doubts that an ArgumentNullException or ArgumentOutOfRange exception would correspond to a network error. If it does, it likely means that the component that really should be catching this exception, isn't.

"Fault tolerance" does not mean "eat every exception so the app doesn't crash" - it means actually knowing the things that can go wrong and handling them correctly.


As a general guideline, don't catch System.Exception. It's a bad idea and a bad code smell indicative of a failure to grasp the purpose of exceptions. I believe it's the result of a dev's belief that exceptions are the error instead of the code that triggered the exception.

I see this failure in production code all the time, and it invariably masks real errors as valid and useful exceptions are caught and swallowed, leaving the application in a bad state. This makes it much trickier to track down the root cause of a failure.

Catching exceptions using the method you've used here is more-or-less the right way to do it. There are a few things you might want to consider improving on, though:

  1. Don't generally treat an ArgumentNullExceptionor ArgumentOutOfRangeException as a runtime network failure (unless it really is). Rather, it should be considered a logic error that causes your program to fail as quickly as possible (so that you can check it out with a debugger as close as possible to the point of failure). This frequently means not catching any ArgumentException at all.

  2. Consider examining the exception hierarchy to find an appropriate base exception that covers the exceptions you're trying to report. E.g., (I haven't looked it up), suppose that three of your exceptions all derived from SocketException. You might save some typing by catching a SocketException instead of the three separate exception. Only do this if you're reporting all socket exceptions, however. (This is basically a more disciplined version of your original attempt to just catch Exception)

  3. Because both lines in every exception handler are identical, you may create a function to do those two lines of work in a single line in the handler. Typical don't-repeat-yourself refactoring. If you want to change the way you report your exception, think about how much easier it would be to change a single function than all those individual handlers.

  4. Just about any significant I/O (network and file come to mind) is going to entail a pretty significant chain of exception handlers just because there's so much that can go wrong. Seeing a lot of error reporting around I/O that may fail isn't an anti-pattern, but it may be a good code smell. Like pine-fresh scent or freshly baked bread. :)


That will certainly catch all exceptions, but that can be poor practice. There are some exceptions that will be hidden or misrepresented that will make testing and debugging your application much more difficult.


You could but you would lose granularity and the ability to handle each issue individually, which isn't the best practice. Usually you would handle different types of exceptions first, just as you have, then if you need to do something with any unhandled exceptions you could add the Exception at the end. Re-throw it once you're done to preserve the stack-trace and let it bubble up.

Keep what you have an add a base case at the end:

catch (ArgumentNullException e) { ... }
catch (EncoderFallbackException e)  { ... }
catch (SocketException e) { ... }
catch (ArgumentOutOfRangeException e)  { ... }
catch (ObjectDisposedException e) { ... }
catch (Exception e)
{
    // not handled by above exceptions, do something if needed
    throw; // after doing what you need, re-throw it
}


As all previous comments suggest, you should catch all the "known" exceptions with exception specific catch block and other unknown, or more appropriately, all "unmatched" exceptions with catch (Exception ex) { ... } or just catch { ... }

However, as specified in your code, you are handling all kind of exceptions in same way. So in this particular case, the output (what you are calling Fault Tolerance) will be the same, but the performance will improve (since the runtime need not compare exception type with given list of types).

Moral of the story : Use single common try-catch in this particular case. But in general, avoid such habit.


It would work, but it would also catch "null reference" exceptions and any other random exception that got thrown.


Yes it would work, but it would not do the same, since all exceptions and not only the specific ones would be catched.

This is usually not what you want, as the general rule is to catch only exceptions which you know how to handle. There are some situations where you need such a catch-all to redirect the exception (like accross thread boundaries or in async calls) or do some cleanup work if something - anything - goes wrong (but then you usually re-throw the exception after doing your work).


It would catch all exceptions which inherit from Exception class. If they all are handled in the same way you can do it but you shouldn't as you can't handle all Exceptions inherited from Exception in the same way.


I actually just read a blog post on this very topic this morning.

You could do something like mentioned in the comments of the post:

catch(Exception e){
    if(    e is ArgumentNullException 
        || e is EncoderFallbackException 
        || e is ...whatever 
    ){
      OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
      OnUpdateNetworkStatusMessage(this, eventArgs);
    } else { throw; } 
}


While you can do that , I'd consider it poor practice and not how you'd want to be structuring your code.

Depending on the exception you may want to do something different. An invalid IP is a different issue than a hardware error and so on. Additionally some errors you might want to notify back to the UI via a delegate or log somewhere using log4net.

But that's just me and I'm far from an expert - so take it for what it's worth


IMO:

Catching Exception would be pretty similar to having methods with parameters that are never more specific of a class than Object; Sure you can do it but is it really the best decision 9 out of 10 times?

What you should consider doing to simplify your code some is Catch exceptions at the highest definition that is relevant.

For instance, in java I would

try{...}
catch( IOException e ) {...}

to catch all IO related exceptions.

There are too many things that can throw too many different types of exceptions, you typically should avoid using the catch-all that is Exception.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜