Two exception management questions - c#

I have a couple of questions around exception management for a website:
in the catch block can I have a static class with a handle exception method that handles the exception like so:
catch (Exception ex)
{
throw ExceptionHandler.HandleException(...);
}
where ExceptionHandler.HandleException is a static method that returns a variable of type System.Exception. Is this a good practice? Any possible problems with this approach? Will it be thread safe?
In my application I have a DAL layer that is called by the Business layer and the Business layer is called by the UI. So, is it a good practice to just re-throw all Custom exceptions so they bubble up right up to the UI where they get displayed whereas System.Exception types get logged and I throw a custom exception in the catch block?
for eg in DAL and Business Layer like so:
catch (CustomExceptionBase ex)
{
throw;
}
catch (Exception sysEx)
{
ICustomExceptionBase ex = new SysException(sysEx);
ex.Handle();
throw BusinessException("Some problem while serving your request");
}
In the UI layer like so
catch (CustomExceptionBase ex)
{
//when custom exception bubbles up; code to display text to user on screen
}
catch (Exception sysEx)
{
ICustomExceptionBase ex = new SysException(sysEx);
ex.Handle();
//display error on screen;
}
Here CustomExceptionBase implements ICustomExceptionBase and inherits Exception. SysException & BusinessException both inherit from CustomExceptionBase.
Thanks for your time...
EDIT
The intent of rethrowing in the system.Exceptions block is so that if there is a fatal error like database connection lost or something similar then I log it for the technical helpdesk and return a ticket number and rethrow the same so the user knows that something went wrong and this is your reference number to follow up. For all custom exceptions in the DAL layer or Business layer, I just bubble it up all the way to the UI where the text gets displayed.

I suspect some of the answers at least are entirely down to your architecture. In the first case it all depends on what ExceptionHandler.HandleException does exactly. Does it generate a new exception based on some criteria or is it just going to return the original exception?
Whether its thread-safe or not entirely depends on its implementation. For example in the following trivial case I'd say it was thread safe:
public static Exception ExceptionHandler.HandleException(Exception ex)
{
return ex;
}
In other cases it could easily be not thread safe. eg:
public static string message;
public static Exception ExceptionHandler.HandleException(Exception ex)
{
message = ex.ToString;
sleep(2000);
return new Exception(message);
}
The latter example clearly has scope for the message variable to be changed by another thread while this one is asleep.
As for the second... Exceptions should be handled where it makes sense to handle them. There is no hard and fast rule. If some part of the code can effect a recovery from an exception (or is willing to skip over it) then catch it at that point and not earlier. If an exception is truly fatal then nothing should be trying to catch it and pretend otherwise so you should just let it bubble right up to the top and do something like alert your user that things have crashed and that you need to restart or whatever.
So really it depends on what your custom exceptions mean. If they just mean "You want to retry this" then that is different from an exception saying "Data integrity has been compromised: 0==1". both of these may be custom so really its for you to decide where to handle things.

Yes, you can call a static exception handler inside a catch block and it will likely be threadsafe as long as you don't reference any static variables.
You should look at Microsoft's Enterprise Library. It has nearly this same design but uses exception policies defined in the web.config to control how the exception is bubbled, wrapped or discarded. Couple that with the Application Logging block and you have a complete solution.

In itself there aren't any technical problems having a static method to handle exceptions / rethrow exceptions, however from a best practices point of view having a single method that magically "handles" exceptions strikes me as a potential code smell. Exceptions are by their very name exceptional, each individual case requires thought to go into it to make sure that you are doing the correct thing and so I find it unlikely that your HandleException method will always be doing something sensible.
As an extreme example I know of one such application where pretty much every single method was wrapped in a try-catch block with a call to an static exception handler method which threw a generic MyApplicationException type. This is an extremely bad idea:
It clutters the code
It makes it harder to make sense of stack traces
It makes it very difficult for callers to catch and handle specific exceptions types
It makes throwing an exception an even bigger performance penalty than before
My favourite was a method which wasn't implemented which looked a bit like this:
void SomeException()
{
try
{
throw new NotImplementedException();
}
catch(Exception ex)
{
throw ExceptionHandler.HandleException(...);
}
}
The worst bit of this of course that it is completely mindless. As I said before exceptions are exceptional - each try ... catch block requires careful thought and consideration to be put into how it should behave, the use of a generic HandleException method is an immediate warning flag that this probably isn't the case.
Rethrowing exceptions
Generally speaking you should only rethrow an exception in two cases:
When you want to add contextual information to an exception (such as the name of the current file being processed)
When you had to catch an exception in order to handle some specific case, e.g. handling an "out of disk space" error
catch (IOException ex)
{
long win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF;
if (win32ErrorCode == ERROR_HANDLE_DISK_FULL || win32ErrorCode == ERROR_DISK_FULL)
{
// Specific "out of disk space" error handling code
}
else
{
throw;
}
}
"Bubbling" (i.e. catching and rethrowing an exception without doing anything with it) is completely unneccessary - this is what exceptions are already designed to do all by themselves!
Handling exceptions
Other people have said "exceptions should be handled where it makes sense" and I have even given this advice myself, but in hindsight I don't think thats particularly useful advice! :)
What people generally mean by that is that you should handle exceptions for specific reasons, and that you should choose where in your application to handle that exception depending on that reason.
For example if you want to display an error message to inform the user that they don't have permission to modify a file if you get an access denied error then you may have a specific try-catch block in your UI code that does this:
catch (IOException ex)
{
long win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF;
if (win32ErrorCode == ERROR_ACCESS_DENIED)
{
// Display "access denied error"
}
else
{
throw;
}
}
Note that this is very specific to this one case that we wish to handle - it catches only the specific exception type were are interested in and performs additional checks to filter down to the specific case we are interested in.
Alternatively if you want to log unhandled errors or gracefully display error messages to the user instead of an IIS 505 error screen then the place to do this is either in Global.asax or through a custom error page - ASP.Net Custom Error Pages
My point is that when handling exceptions we are are thinking carefully about what it is we want to achieve in terms of application functionality (e.g. retry logic, error messages, logging etc...) and implementing our exception handling logic to specifically address those requirements in the most targeted way possible - there is no magic exception handing framework and there is no boilerplate code.
Avoid exceptions entirely whenever possible!
I usually find that the best strategy is simply to avoid exceptions entirely whever possible! For example if your page parses user enter numbers and you want to display validation messages when they enter stupid values then validate your input up-front instead of catching exceptions:
Bad:
void DoSomething()
{
int age = int.Parse(ageTextBox.Text);
if (age < 0)
{
throw new ArgumentOutOfRangeException("age must be positive");
}
if (age >= 1000)
{
throw new ArgumentOutOfRangeException("age must be less than 1000");
}
}
void Button_Click(object sender, EventArgs e)
{
try
{
DoSomething();
}
catch (Exception ex)
{
DisplayError(ex.Message);
}
}
Good:
void Button_Click(object sender, EventArgs e)
{
int age;
if (!int.TryParse(ageTextBox.Text, out age))
{
DisplayError("Invalid age entered");
}
if (age < 0)
{
DisplayError("age must be positive");
}
if (age >= 1000)
{
DisplayError("age must be less than 1000");
}
DoSomething();
}
Users enter invalid data all of the time - handling this is really application logic and shouldn't fall into the real of exception handling - its certainly not an event that I would call "exceptional".
Of course this isn't always possible, however I find that using this strategy simplifies the code and makes it easier to follow application logic.

First of all we need to consider Exception types, In any business exception can be either BusinessException or Technical/SystemException.
In BusinessException we can send custom exceptions with error
details.
In Technical/System Exception we should not handle it, but let it
popup to UI layer.UI Can decide what error should be displayed in
case of exceptions.
In your approaches, if you handle exception or throw the custom
exception the call trace is lost.

Related

What is a better way to handle exceptions than the following?

At first, I was going to do something like the following:
public void WriteToFile(string filePath, string contents)
{
try
{
File.WriteAllText(filePath, contents)
}
catch(Exception ex)
{
//Log error
}
}
But then I decided to catch all the specific exceptions for the method WriteAllText, like the following:
public void WriteToFile(string filePath, string contents)
{
try
{
File.WriteAllText(filePath, contents);
}
catch (IOException ex)
{
//An I/O error occured when opening the file
}
catch (ArgumentException ex)
{
//The exception that is thrown when one of the arguments provided to a method
that is not valid.
}
catch (UnauthorizedAccessException ex)
{
//Unauthorized access
}
catch (SecurityException ex)
{
//Security exception
}
catch (NotSupportedException ex)
{
//Invoked method not supported
}
}
The above is very verbose and with other methods, it could be more. Is there a better way to do this so I don't have to write so many catch statements. Also, if an exception is caught, is it best to return from it, log it. I always get confused on how to handle it.
I have noticed some confusion. I am going to handle the exceptions, I left out handling the exception to keep this short. I am going to make use of the ex variable. The question is more about doing just catch(Exception ex) or multiple catch statements.
I also bring this up because I always here that it is better to handle specific exceptions rather than a catch-all. If I have misunderstood this, please clarify on what it means.
It depends on how you are handling the exception. For example, if a SecurityException will cause you to present a dialog to the user to provide their credentials, then you should have a separate catch clause. If not, there is no need to explicitly call them all out.
E.g.
try
{
File.WriteAllText(filePath, contents);
}
catch (SecurityException ex)
{
//present dialog
}
catch (Exception ex)
{
//All other exceptions handled the same
}
Typicaly, your try/catch statements will be much further up the call stack from what you are showing in the question. There are two major reasons for this. First is that a low-level method will not know how to deal with an exception that happens within it, because it does not have enough context. If a low-level method (such as one that saves a document) does know enough about its circumstances to handle the exceptions, then that is a sign of a leaky abstraction. Second is that the program flow at higher levels will depend on whether the save operation succeeded or not. For these reasons, all of these types of exceptions are best delt with at the highest levels, such as in the UI layer.
That said, sometimes a long list of exceptions—as you have it—is exactly the way to go. If you need to handle a bunch of different circumstances, then it calls for a bunch of different catch statements, and that's just the way it goes.
Some of those exceptions, however, do not need to be caught. For example, an ArgumentException never needs to be caught. Instead, it is best just to pass the correct arguments every time. The only time an ArgumentException will ever need to be caught is if you are calling into a poory designed library in which you cannot know beforehand whether an argument is good or not. A well-designed library will provide alternatives to this.
So the list of catch statements could be made shorter, just by judiciously examining the circumstances of each type of exception and determining which ones are actually expected to happen.
I agree with SLaks above. If you don't handle it there is no reason in catching specific exceptions. If you can handle certain exceptions but not others you should have a catch all that at least logs vital information about the exception.
The best method very much depends on the nature of your application and the expectations of the user. If you are creating a Word processing application and your operation above was to save the user's document, swallowing the exception and logging without notifying the user would be very bad! In this context, I would catch the specific exceptions so that I could better report to the user what the problem is.
If instead the file you are saving is non-critical, e.g. a period caching of some data that is retained in memory, you might want to simply log and not notify the user. In this context, I would go for a generic catch-all and just log the exception details.

throw exception in the try block rather than catch block?

I've inherited code in our project which looks like this. It's a method in a class.
protected override bool Load()
{
DataAccess.SomeEntity record;
try
{
record = _repository.Get(t => t.ID.Equals(ID));
if (record == null)
{
throw new InvalidOperationException("failed to initialize the object.");
}
else
{
this.ID = record.ID;
// this.OtherProperty = record.SomeProperty;
// etc
}
}
catch (Exception)
{
throw;
}
return true;
}
If I then call this Load method from my UI layer, I'd probably want to have a try catch block to catch any exception caused by the failure to Load the instance, e.g. InvalidOperationException, but the above code feels wrong to me.
Won't the InvalidOperationException be swallowed by the catch statement? that catch statement will also catch potential problems with _repository.Get, as well as potential problems with the setting of properties if the record is valid.
I thought I should perhaps restructure it by adding more try catch statements to handle the Get operation and property setting operations separately, or add more catch blocks handling different exceptions, but I asked a colleague, and he suggested that the try catch is irrelevant in this case, and should be removed completely, leaving it like:
protected override bool Load()
{
DataAccess.SomeEntity record;
record = _repository.Get(t => t.ID.Equals(ID));
if (record == null)
{
throw new InvalidOperationException("failed to initialize the object.");
}
else
{
this.ID = record.ID;
// this.OtherProperty = record.SomeProperty;
// etc
}
return true;
}
I'd like some second opinions, I've only just started taking an interest in exception handling, so I'd like to make sure I am doing it the right way according to best practices.
When you do this:
catch (Exception)
{
throw;
}
You are essentially not handling the exception. That does not however mean you are ignoring it. The throw statement will propagate the exception up the stack. For the sake of clean readable code your final example is much better.
If you're catching exceptions in the calling method ( Ithink) you should only catch exceptions which you expect. If the exception is a problem for Load(), then throw a new exception to the calling method, with better information about the exception.
Excellent! You are definitely on the right track. The previous implementation doing nothing other than re-throwing exceptions which is unnecessary. You should only handle specific exceptions that you are anticipating in the business layer, otherwise let them naturally go up the call stack up to the UI layer.
As best practice, only re-throw exceptions when you want to add some additional debug information, in which case you will need to define a custom exception
The exception will be caught by the catch statement but since it has a throw statement, it'll throw the exception back out. This has the same effect as if you didn't have a try/catch at all, so your colleague is right in suggesting leaving it out.
There isn't much of a point to adding exception-handling code if you don't actually handle the exception in any way.
I agree with your colleague, you should only catch exceptions that you know need to be caught. I typically leave out any try catch blocks unless I know exactly why I need it in a particular situation. This is because you tend to hide the real bugs in your code if you just put try catch block around everything. Leave the error handling off until you absolutely need it - start off with a single global error handler at the highest point in the application - if this is asp.net you can hook the application error event and log errors there, but my point is don't add try catch blocks unless you know why your adding them and write code that handles error cases not traps them.
Enjoy!

Common programming mistakes in .Net when handling exceptions? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are some of the most common mistakes you've seen made when handling exceptions?
It seems like exception handling can be one of the hardest things to learn how to do "right" in .Net. Especially considering the currently #1 ranked answer to Common programming mistakes for .NET developers to avoid? is related to exception handling.
Hopefully by listing some of the most common mistakes we can all learn to handle exceptions better.
What are some of the most common mistakes you've seen made when handling exceptions?
I can think of lots.
First read my article on categorization of exceptions into vexing, boneheaded, fatal and exogenous:
http://ericlippert.com/2008/09/10/vexing-exceptions/
Some common errors:
Failure to handle exogenous exceptions.
Failure to handle vexing exceptions.
Construction of methods that throw vexing exceptions.
Handling exceptions that you actually cannot handle, like fatal exceptions.
Handling exceptions that hide bugs in your code; don't handle a boneheaded exception, fix the bug so that it isn't thrown in the first place
Security error: failure to the unsafe mode
try
{
result = CheckPassword();
if (result == BadPassword) throw BadPasswordException();
}
catch(BadPasswordException ex) { ReportError(ex); return; }
catch(Exception ex) { LogException(ex); }
AccessUserData();
See what happened? We failed to the unsafe mode. If CheckPassword threw NetworkDriverIsAllMessedUpException then we caught it, logged it, and accessed the user's data regardless of whether the password was correct. Fail to the safe mode; when you get any exception, assume the worst.
Security error: production of exceptions which leak sensitive information, directly or indirectly.
This isn't exactly about handling exceptions in your code, it's about producing exceptions which are handled by hostile code.
Funny story. Before .NET 1.0 shipped to customers we found a bug where it was possible to call a method that threw the exception "the assembly which called this method does not have permission to determine the name of file C:\foo.txt". Great. Thanks for letting me know. What is stopping said assembly from catching the exception and interrogating its message to get the file name? Nothing. We fixed that before we shipped.
That's a direct problem. An indirect problem would be a problem I implemented in LoadPicture, in VBScript. It gave a different error message depending upon whether the incorrect argument is a directory, a file that isn't a picture, or a file that doesn't exist. Which means you could use it as a very slow disk browser! By trying a whole bunch of different things you could gradually build up a picture of what files and directories were on someone's hard disk. Exceptions should be designed so that if they are handled by untrustworthy code, that code learns none of the user's private information from whatever they did to cause the exception. (LoadPicture now gives much less helpful error messages.)
Security and resource management error: Handlers which do not clean up resources are resource leaks waiting to happen. Resource leaks can be used as denial-of-service attacks by hostile partial trust code which deliberately creates exceptions-producing situations.
Robustness error: Handlers must assume that program state is messed up unless handling a specific exogenous exception. This is particularly true of finally blocks. When you're handling an unexpected exception, it is entirely possible and even likely that something is deeply messed up in your program. You have no idea if any of your subsystems are working, and if they are, whether calling them will make the situation better or worse. Concentrate on logging the error and saving user data if possible and shut down as cleanly as you can. Assume that nothing works right.
Security error: temporary global state mutations that have security impacts need to be undone before any code that might be hostile can run. Hostile code can run before finally blocks run! See my article on this for details:
http://blogs.msdn.com/ericlippert/archive/2004/09/01/224064.aspx
Re-throwing exceptions like this:
try
{
// some code here
}
catch(Exception ex)
{
// logging, etc
throw ex;
}
This kills the stack trace, making is far less usable. The correct way to rethrow would be like this:
try
{
// some code here
}
catch(Exception ex)
{
// logging, etc
throw;
}
Catching all exceptions when in many cases you should attempt to catch specific exceptions:
try {
// Do something.
} catch (Exception exc) {
// Do something.
}
Rather than:
try {
// Do something.
} catch (IOException exc) {
// Do something.
}
Exceptions should be ordered from most specific to least.
Rethrowing an exception with a meaningless message.
try
{
...
}
catch (Exception ex)
{
throw new Exception("An error ocurred when saving database changes").
}
You won't believe how often I see code like this running in production.
Nobody is talking about seeing empty catch blocks like these....
try{
//do something
}
catch(SQLException sqex){
// do nothing
}
Also never use Exception handling for creating alternate method flows...
try{
//do something
}catch(SQLException sqex){
//do something else
}
Not using using on IDisposable objects:
File myFile = File.Open("some file");
callSomeMethodWhichThrowsException(myFile);
myFile.Close();
myFile does not get closed until myFile's finalizer is called (which may be never) because an exception was thrown before myFile.Close() was called.
The proper way to do this is
using(File myFile = File.Open("some file"))
{
callSomeMethodWhichThrowsException(myFile);
}
This gets translated by the compiler into something like:
File myFile = File.Open("some file");
try
{
callSomeMethodWhichThrowsException(myFile);
}
finally
{
if(myFile != null)
myFile.Dispose(); //Dispose() calls Close()
}
So the file gets closed even in the face of exceptions.
Forget to set the inner exception when rethrowing a catched exception
try
{
...
}
catch (IOException ioException)
{
throw new AppSpecificException("It was not possible to save exportation file.")
// instead of
throw new AppSpecificException("It was not possible to save exportation file.", ioException);
}
When I posted this answer, I forget to mention that we should always consider when to include inner exception or not due to security reasons. As Eric Lippert pointed out on another answer for this topic, some exceptions can provide sensitive information about the implementation details of the server. Thus, if the caller who will be handling the exception is not trusted, it is not a good idea to include the inner exception information.
Empty catch:
//What's the point?
catch()
{}
Rethrowing:
//Exceptions are for *adding* detail up the stack
catch (Exception ex)
{throw ex;}
Assuming an exception that covers many scenarios was something specific. A real life scenario was a web app where the exception handling always assumed all errors were session time outs and logged and reported all errors as session time outs.
Another example:
try
{
Insert(data);
}
catch (SqlException e)
{
//oh this is a duplicate row, lets change to update
Update(data);
}
To log Exception.Message instead of Exception.ToString()
Many times, I see code logging only the exception message while it should log the return of ToString method. ToString provides much more information about the exception than the Message. It includes information like inner exception and stack trace besides the message.
Trying to catch OutOfMemoryException or StackOverflowException - those lead to a shutdown of the runtime, hence to way to catch them from within the same Process (or even from the CLR as a whole?)
OutOfMemoryException: The exception that is thrown when there is not enough memory to continue the execution of a program.
"Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow."
Failing to catch possible exceptions inside a catch handler. This can cause the wrong exception to be propagated upwards.
For example:
try
{
DoImportantWork();
}
catch
{
Cleanup();
throw;
}
What happens if Cleanup() throws an exception? You don't want to see an Exception pointing to the Cleanup() method in this catch handler. You want the original error. You could try to log the cleanup error, but even your logging code needs exception handling to avoid throwing exceptions from it.
try
{
DoImportantWork();
}
catch
{
try
{
Cleanup();
}
catch
{
// We did our best to clean up, and even that failed.
// If you try to log this error, the logging may throw yet another Exception.
}
throw;
}
Wrong
try
{
// Do something stupid
}
catch
{
// ignore the resulting error because I'm lazy, and later spend
// a week trying to figure out why my app is crashing all over
// the place.
}
Better
try
{
/// do something silly.
}
catch (InvalidOperationException ex)
{
/// respond, or log it.
}
catch (Exception e)
{
/// log it.
}
Using exceptions for normal flow control. Exceptions should exceptional. If it's a good / expected operation, use return values, etc.

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 e)
{
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:
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.
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)
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.
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.

Exceptions from SoapHttpClientProtocol.Invoke Method .NET web service

I am calling a web service from a C# forms based app.
ServReturnType obj = ServProxyClass(int i, int k);
I have the potential to get back an exception. The exception could be that the service didn't connect at all, that there was a failure on the receive, but the original message went, or anything in between. I then need to make a decision based on the exception thrown, either on the type, or the message, or both, as to do one of two actions next.
try
{
ServReturnType obj = ServProxyClass(int i, int k);
}
catch (WebException ex)
{
DoAction1();
}
catch(SocketException ex)
{
DoAction2();
}
catch(SoapException ex)
{
DoAction1()
}
The issues is, my choice of subsequent actions depends on whether or not the first call made it to the server before failing. How can I find a list of all possible exceptions thrown, and what they might mean, as this is all code in the framework. I looked that MSDN docs, and saw that SoapHttpClientProtocol.Invoke can throw a SoapException, however there are methods called by this method that bubble up System.Net.WebExceptions. So I need a list of the whole call stack and what it can throw, and what that means.
Any ideas?
Update 1
Darin, your answer more or less confirms my suspicions that what I want doesn't really make sense. I have opted to do more detective work first, then use that to decide what to do next. Unfortunately in this case, since we are processing credit cards, it really matters what exactly has happened, and whether or not we sent data.
The complete list of exceptions that can be thrown from a web service call is so vast that I really don't think that it is a good idea to test for every type of exception possible. In many cases it would be enough to catch for SoapException which could contain some business errors transmitted through the SOAP Fault Element and every other exception could be considered as a non handled error:
try
{
ServReturnType obj = ServProxyClass(int i, int k);
}
catch(SoapException ex)
{
//Serialize and analyze the fault message from the exception to obtain more info.
DoSomethingWithTheInfo();
}
catch(Exception ex)
{
LogTheExceptionSoThatLaterYouKnowWhatHappened(ex);
SayToTheUserThatSomethingTerriblyWrongHappened();
}
Here's a nice article explaining how to raise and handle SoapExceptions.

Categories

Resources