Try - Catch return strategy - c#

When using try-catch in methods, if you want you application to continue even if errors come along, is it okay to return the default value as return through the catch block, and log the error for later review?
For Example:
public static string GetNameById(int id)
{
string name;
try
{
//Connect to Db and get name - some error occured
}
catch(Exception ex)
{
Log(ex);
name = String.Empty;
}
return name;
}
Example 2:
public static string GetIdByName(string name)
{
int id;
try
{
//Connect to Db and get id- some error occured
}
catch(Exception ex)
{
Log(ex);
id = 0;
}
return id;
}
Is it okay to return any default value (depending on the return type of the method ...???) so that the application logic that required the result from this method do not crash and keeps going ....
Thanks in advance...
Regards.

The advice for exception handling is that mostly you should only catch exceptions that you can do something about (e.g. retry an operation, try a different approach, elevate security etc). If you have logging elsewhere in your application at a global level, this kind of catch-log-return is unnecessary.
Personally - typically - in this situation I'd do this:
public static string GetNameById(int id)
{
string name;
try
{
//Connect to Db and get name - some error occured
}
catch(Exception ex)
{
Log(ex);
throw; // Re-throw the exception, don't throw a new one...
}
return name;
}
So as usual - it depends.
Be aware of other pitfalls though, such as the calling method not being aware that there was a failure, and continuing to perform work on the assumption that the method throwing the exception actually worked. At this point you start the conversation about "return codes vs. throwing exceptions", which you'll find a lot of resources for both on SO.com and the internets in general.

I do not think that is a good solution. In my opinion it would be better to let the caller handle the exception. Alternatively you can catch the exception in the method and throw a custom exception (with the caught exception as the inner exception).
Another way of going about it would be to make a TryGet method, such as:
public static bool TryGetNameById(int id, out string name)
{
try
{
//Connect to Db and get name - some error occured
name = actualName
return true;
}
catch(Exception ex)
{
Log(ex);
name = String.Empty;
return false;
}
}
I think this approach is more intention revealing. The method name itself communicates that it may not always be able to produce a useful result. In my opinion this is better than returning some default value that the caller has to be able to know about to do the correct business logic.

My opinion is I'll never mute errors.
If some exception is thrown, it should be treated as a fatal error.
Maybe the problem is throwing exceptions for things that aren't exceptions. For example, business validation shoudn't be throwing such exceptions.
I'd prefer to validate the business and translate the errors in "broken rules" and transmit them to the presentation or wherever, that would save CPU and memory because there's no stack trace.
Another situation is a data connection loss or another situation that makes the application fall in a wrong state. Then, I'd prefer to log the error and prompt the user to re-open the application or maybe the application may restart itself.
I want to make you some suggestion: have you ever heard about PostSharp? Check it, you can implement that exception logging with an AOP paradigm.

It is advised that you only catch errors that you can handle and recover from. Catching and consuming exceptions that you cannot handle is bad form. However, some environments / applications define strict rules that go against this ideal behaviour.
In those cases, I would say in cases you don't have a choice, you can do what you like with returns - it is up to your application to work with them.
Based on the assumption that your application can handle any sort of failure in trying to get an ID, then returning a default ID is a good enough choice. You can go further and use something like the special case pattern to return empty / missing objects, but for simple data types this seems unwarranted.

this depends very much on the context and on the way your calling method is designed. I have used to return default values in the past as you are doing now and I understood only afterwards that it was deeply wrong...
you should imagine the catch block to throw the exception back, after logging it properly, then the calling method could have another try catch and depending on the severity of the error could inform the user or behave accordingly.
the fact is that if you return an empty string, in some cases, could be that the caller "thinks" there is a user with empty name, while would probably be better to notify the user that the record was not found, for example.
depending on the way your logger works you could log the exception only where you handle it and not in all catches...

That depends on what you want. If it's important for you that you log the exception, but that everything else keeps working, then this is - in my honest opinion- ok.
On the other hand: if an exception occurs, you have to make sure this does not have an impact on the further working of your application.

The point of a try/catch is to allow you to catch and handle errors in a graceful manor, allowing application execution to continue, rather than simply crashing the application and stopping execution.
Therefore it is perfectly acceptable to return a default value. However, be sure that all following code will continue to function if a default value is returned rather than causing further errors.
Eg - in your example, if the DB connection fails, ensure there are no further commands to edit / retrieve values from the database.

It REALLY depends. In most scenarios it is not - problems i that if there is a scenario specific issue you amy never find out. Soemtiems a recovery attempt is good. This normalyl depends on circumstances and actual logic.
The scenarios where "swallow and document" are really valid are rare and far in between in the normal world. They come in more often when writing driver type of thigns (like loaded moduels talkign to an external system). Whether a return value or default(T) equivalent maeks sense also depends.
I would say in 99% of the cases let the exception run up. In 1% of the cases it may well make sense to return some sensible default.

It is better to log the exception but then re-trow it so that it can be properly handled in the upper layers.
Note: the "log the exception part" is of course optional and depends a lot on your handling strategy(will you log it again somewhere else?)
Instead of making the app not crash by swalowing exception, it is better to let them pass and try to find the root cause why they were thrown in the first place.

Depends on what you want your app to do...
For example, display a friendly message, "Cannot Login" if you get a SqlException when trying to connect to the Database is OK.
Handling all errors is sometimes considered bad, although people will disagree...
Your application encountered an exception you did not expect, you can no longer be 100% sure what state your application is in, which lines of codes executed and which didn't, etc. Further reading on this: http://blogs.msdn.com/b/larryosterman/archive/2005/05/31/423507.aspx.
And more here : http://blogs.msdn.com/b/oldnewthing/archive/2011/01/20/10117963.aspx

I think the answer would have to be "it depends".
In some cases it may be acceptable to return an empty string from a function in case of an error. If you are looking up somebody's address to display then an empty string works fine rather than crashing the whole thing.
In other cases it may not work so well. If you are returning a string to use for a security lookup for example (eg getSecurityGroup) then you are going to have very undesired behaviour if you return the wrong thing and you might be better off keeping the error thrown and letting the user know something has gone wrong rather than pretending otherwise.
Even worse might be if you are persisting data provided to you by the user. Something goes wrong when you are getting their data, you return a default and store that without even telling them... That's gotta be bad.
So I think you need to look at each method where you are considering this and decide if it makes sense to throw an error or return a default value.
In fact as a more general rule any time you catch an error you should be thinking hard about whether it is an acceptable error and continuing is permissable or whether it is a show stopping error and you should just give up.

Related

Better handling of exceptions occurring in methods connecting to internet

I have lots of methods which connects to internet to get something. So I need to handle the WebExceptions which can occur. But I would like to reduce try catch blocks in my code which uses these methods, because it looks ugly and difficult to look. What I'm doing right now is return a Tuple with an enum which I can use to see if the method failed or succeeded etc. Then I use a switch and case blocks to handle it. For example:
Tuple<GetIpReturn, string> ip = await _user.GetIp();
GetIpLocksReturn returnValue = ip.Item1;
switch (returnValue) {
case GetIpLocksReturn.InternetError:
// WebException occured
break;
case GetIpLocksReturn.AuthError:
//
break;
case GetIpLocksReturn.Success:
// Use ip.Item2 (The ip string)
break;
}
But this also looks messy with those break statements.
Usually the error cases will have very few lines of code. Is there a better way of doing this? (Maybe using delegates?)
IMHO, you should just let the exceptions happen. Wrapping exceptions in return values that include failure codes is antithetical to normal .NET idioms, requires more code in both caller and callee (including the added runtime cost of additional try/catch handling), and doesn't achieve anything that couldn't also be achieved using exceptions.
Converting exceptions to failure codes also loses potentially useful information, such as stack traces and HRESULT values.
Note that if you want to add information to exceptions, your implementation can catch exceptions that happen and then throw a new custom exception, for which you've provided the original exception as the InnerException property value.
For related discussion, see also:
C# why throw errors
Should my method throw its own exception, or let .NET throw if a file doesn't exist?
They aren't exactly the same question, but they both include discussion on why exceptions are preferred in .NET code.
My answer is regarding handled exceptions, meaning it happens enough and we know what to do about it; it's routine. In my application, for example, we simply show a message to the user in these well defined cases. Of course that depends on the application. I agree with Peter that unhandled exceptions should go into catches, not switches.
Just return a class that contains a) a friendly error message or blank, b) the data and c) the bool Success. The Status code and / or exception data you can put in there too for debugging. usually you just want to display or log the error message if not Success, and usually you just want use the data if Success = true. Success tells you if you can continue after the api call.
To sum up, OO to the rescue. Try to make the return class stronger so you can eliminate the switch based on what you know you eventually will do with these properties (e.g., display error message).

Empty catch blocks

I sometimes run into situations where I need to catch an exception if it's ever thrown but never do anything with it. In other words, an exception could occur but it doesn't matter if it does.
I recently read this article about a similar thing: http://c2.com/cgi/wiki?EmptyCatchClause
This person talks about how the comment of
// should never occur
is a code smell and should never appear in code. They then go onto explain how the comment
// don't care if it happens
is entirely different and I run into situations like this myself. For example, when sending email I do something similar to this:
var addressCollection = new MailAddressCollection();
foreach (string address in addresses)
{
try
{
addressCollection.Add(address);
}
catch (Exception)
{
// Do nothing - if an invalid email occurs continue and try to add the rest
}
}
Now, you may think that doing this is a bad idea since you would want to return to the user and explain that one or more messages could not be sent to the recipient. But what if it's just a CC address? That's less important and you may still want to send the message anyway even if one of those addresses was invalid (possibly just a typo).
So am I right to use an empty catch block or is there a better alternative that I'm not aware of?
You are completely right to use an empty catch block if you really want to do nothing when a certain type of exception occurs. You could improve your example by catching only the types of exceptions which you expect to occur, and which you know are safe to ignore. By catching Exception, you could hide bugs and make it harder for yourself to debug your program.
One thing to bear in mind regarding exception handling: there is a big difference between exceptions which are used to signal an error condition external to your program, which is expected to happen at least sometimes, and exceptions which indicate a programming error. An example of the 1st would be an exception indicating that an e-mail couldn't be delivered because the connection timed out, or a file couldn't be saved because there was no disk space. An example of the 2nd would be an exception indicating that you tried to pass the wrong type of argument to a method, or that you tried to access an array element out of bounds.
For the 2nd (programming error), it would be a big mistake to just "swallow" the exception. The best thing to do is usually to log a stack trace, and then pop up an error message telling the user that an internal error has happened, and that they should send their logs back to the developers (i.e. you). Or while developing, you might just make it print a stack trace to the console and crash the program.
For the 1st (external problem), there is no rule about what the "right" thing is to do. It all depends on the details of the application. If you want to ignore a certain condition and continue, then do so.
IN GENERAL:
It's good that you are reading technical books and articles. You can learn a lot from doing so. But please remember, as you read, you will find lots of advice from people saying that doing such-and-such a thing is always wrong or always right. Often these opinions border on religion. NEVER believe that doing things a certain way is absolutely "right" because a book or article (or an answer on SO... <cough>) told you so. There are exceptions to every rule, and the people writing those articles don't know the details of your application. You do. Make sure that what you are reading makes sense, and if it doesn't, trust yourself.
An empty catch block is fine in the right place - though from your sample I would say you should cetagorically NOT be using catch (Exception). You should instead catch the explicit exception that you expect to occur.
The reason for this is that, if you swallow everything, you will swallow critical defects that you weren't expecting, too. There's a world of difference between "I can't send to this email address" and "your computer is out of disk space." You don't want to keep trying to send the next 10000 emails if you're out of disk space!
The difference between "should not happen" and "don't care if it happens" is that, if it "should not happen" then, when it does happen, you don't want to swallow it silently! If it's a condition you never expected to occur, you would typically want your application to crash (or at least terminate cleanly and log profusely what's happened) so that you can identify this impossible condition.
If an exception should never be thrown then there is no point catching it - it should never happens and if it does you need to know about it.
If there are specific scenarios that can cause a failure that you are OK with then you should catch and test for those specific scenarios and rethrow in all other cases, for example
foreach (string address in addresses)
{
try
{
addressCollection.Add(address);
}
catch (EmailNotSentException ex)
{
if (IsCausedByMissingCcAddress(ex))
{
// Handle this case here e.g. display a warning or just nothing
}
else
{
throw;
}
}
}
Note that the above code catches specific (if fictional) exceptions rather than catching Exception. I can think of very few cases where it is legitimate to catch Exception as opposed to catching some specific exception type that you are expecting to be thrown.
Many of the other answers give good reasons when it would be ok to catch the exception, however many classes support ways of not throwing the Exception at all.
Often these methods will have the prefix Try in front of them. Instead of throwing a exception the function returns a Boolean indicating if the task succeeded.
A good example of this is Parse vs TryParse
string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
//This code is only executed if "s" was parsed succesfully.
aCollectionOfInts.Add(i);
}
If you try the above function in a loop and compare it with its Parse + Catch equilvilant the TryParse method will be much faster.
Using an empty catch block just swallows the Exception, I would always handle it, even if it is reporting back to you that an Exception occurred.
Also catching the generic Exception is bad practice due to the fact it can hide bugs in your application. For example, you may have caught an ArgumentOutOfRange exception which you did not realize was happening and then swallowed it (I.e. not done anything with it).

How using try catch for exception handling is best practice

while maintaining my colleague's code from even someone who claims to be a senior developer, I often see the following code:
try
{
//do something
}
catch
{
//Do nothing
}
or sometimes they write logging information to log files like following try catch block
try
{
//do some work
}
catch(Exception exception)
{
WriteException2LogFile(exception);
}
I am just wondering if what they have done is the best practice? It makes me confused because in my thinking users should know what happens with the system.
My exception-handling strategy is:
To catch all unhandled exceptions by hooking to the Application.ThreadException event, then decide:
For a UI application: to pop it to the user with an apology message (WinForms)
For a Service or a Console application: log it to a file (service or console)
Then I always enclose every piece of code that is run externally in try/catch :
All events fired by the WinForms infrastructure (Load, Click, SelectedChanged...)
All events fired by third party components
Then I enclose in 'try/catch'
All the operations that I know might not work all the time (IO operations, calculations with a potential zero division...). In such a case, I throw a new ApplicationException("custom message", innerException) to keep track of what really happened
Additionally, I try my best to sort exceptions correctly. There are exceptions which:
need to be shown to the user immediately
require some extra processing to put things together when they happen to avoid cascading problems (ie: put .EndUpdate in the finally section during a TreeView fill)
the user does not care, but it is important to know what happened. So I always log them:
In the event log
or in a .log file on the disk
It is a good practice to design some static methods to handle exceptions in the application top level error handlers.
I also force myself to try to:
Remember ALL exceptions are bubbled up to the top level. It is not necessary to put exception handlers everywhere.
Reusable or deep called functions does not need to display or log exceptions : they are either bubbled up automatically or rethrown with some custom messages in my exception handlers.
So finally:
Bad:
// DON'T DO THIS; ITS BAD
try
{
...
}
catch
{
// only air...
}
Useless:
// DON'T DO THIS; IT'S USELESS
try
{
...
}
catch(Exception ex)
{
throw ex;
}
Having a try finally without a catch is perfectly valid:
try
{
listView1.BeginUpdate();
// If an exception occurs in the following code, then the finally will be executed
// and the exception will be thrown
...
}
finally
{
// I WANT THIS CODE TO RUN EVENTUALLY REGARDLESS AN EXCEPTION OCCURRED OR NOT
listView1.EndUpdate();
}
What I do at the top level:
// i.e When the user clicks on a button
try
{
...
}
catch(Exception ex)
{
ex.Log(); // Log exception
-- OR --
ex.Log().Display(); // Log exception, then show it to the user with apologies...
}
What I do in some called functions:
// Calculation module
try
{
...
}
catch(Exception ex)
{
// Add useful information to the exception
throw new ApplicationException("Something wrong happened in the calculation module:", ex);
}
// IO module
try
{
...
}
catch(Exception ex)
{
throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex);
}
There is a lot to do with exception handling (Custom Exceptions) but those rules that I try to keep in mind are enough for the simple applications I do.
Here is an example of extensions methods to handle caught exceptions a comfortable way. They are implemented in a way they can be chained together, and it is very easy to add your own caught exception processing.
// Usage:
try
{
// boom
}
catch(Exception ex)
{
// Only log exception
ex.Log();
-- OR --
// Only display exception
ex.Display();
-- OR --
// Log, then display exception
ex.Log().Display();
-- OR --
// Add some user-friendly message to an exception
new ApplicationException("Unable to calculate !", ex).Log().Display();
}
// Extension methods
internal static Exception Log(this Exception ex)
{
File.AppendAllText("CaughtExceptions" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", DateTime.Now.ToString("HH:mm:ss") + ": " + ex.Message + "\n" + ex.ToString() + "\n");
return ex;
}
internal static Exception Display(this Exception ex, string msg = null, MessageBoxImage img = MessageBoxImage.Error)
{
MessageBox.Show(msg ?? ex.Message, "", MessageBoxButton.OK, img);
return ex;
}
Best practice is that exception handling should never hide issues. This means that try-catch blocks should be extremely rare.
There are 3 circumstances where using a try-catch makes sense.
Always deal with known exceptions as low-down as you can. However, if you're expecting an exception it's usually better practice to test for it first. For instance parse, formatting and arithmetic exceptions are nearly always better handled by logic checks first, rather than a specific try-catch.
If you need to do something on an exception (for instance logging or roll back a transaction) then re-throw the exception.
Always deal with unknown exceptions as high-up as you can - the only code that should consume an exception and not re-throw it should be the UI or public API.
Suppose you're connecting to a remote API, here you know to expect certain errors (and have things to in those circumstances), so this is case 1:
try
{
remoteApi.Connect()
}
catch(ApiConnectionSecurityException ex)
{
// User's security details have expired
return false;
}
return true;
Note that no other exceptions are caught, as they are not expected.
Now suppose that you're trying to save something to the database. We have to roll it back if it fails, so we have case 2:
try
{
DBConnection.Save();
}
catch
{
// Roll back the DB changes so they aren't corrupted on ANY exception
DBConnection.Rollback();
// Re-throw the exception, it's critical that the user knows that it failed to save
throw;
}
Note that we re-throw the exception - the code higher up still needs to know that something has failed.
Finally we have the UI - here we don't want to have completely unhandled exceptions, but we don't want to hide them either. Here we have an example of case 3:
try
{
// Do something
}
catch(Exception ex)
{
// Log exception for developers
WriteException2LogFile(ex);
// Display message to users
DisplayWarningBox("An error has occurred, please contact support!");
}
However, most API or UI frameworks have generic ways of doing case 3. For instance ASP.Net has a yellow error screen that dumps the exception details, but that can be replaced with a more generic message in the production environment. Following those is best practice because it saves you a lot of code, but also because error logging and display should be config decisions rather than hard-coded.
This all means that case 1 (known exceptions) and case 3 (one-off UI handling) both have better patterns (avoid the expected error or hand error handling off to the UI).
Even case 2 can be replaced by better patterns, for instance transaction scopes (using blocks that rollback any transaction not committed during the block) make it harder for developers to get the best practice pattern wrong.
For instance suppose you have a large scale ASP.Net application. Error logging can be via ELMAH, error display can be an informative YSoD locally and a nice localised message in production. Database connections can all be via transaction scopes and using blocks. You don't need a single try-catch block.
TL;DR: Best practice is actually to not use try-catch blocks at all.
An exception is a blocking error.
First of all, the best practice should be don't throw exceptions for any kind of error, unless it's a blocking error.
If the error is blocking, then throw the exception. Once the exception is already thrown, there's no need to hide it because it's exceptional; let the user know about it (you should reformat the whole exception to something useful to the user in the UI).
Your job as software developer is to endeavour to prevent an exceptional case where some parameter or runtime situation may end in an exception. That is, exceptions mustn't be muted, but these must be avoided.
For example, if you know that some integer input could come with an invalid format, use int.TryParse instead of int.Parse. There is a lot of cases where you can do this instead of just saying "if it fails, simply throw an exception".
Throwing exceptions is expensive.
If, after all, an exception is thrown, instead of writing the exception to the log once it has been thrown, one of best practices is catching it in a first-chance exception handler. For example:
ASP.NET: Global.asax Application_Error
Others: AppDomain.FirstChanceException event.
My stance is that local try/catches are better suited for handling special cases where you may translate an exception into another, or when you want to "mute" it for a very, very, very, very, very special case (a library bug throwing an unrelated exception that you need to mute in order to workaround the whole bug).
For the rest of the cases:
Try to avoid exceptions.
If this isn't possible: first-chance exception handlers.
Or use a PostSharp aspect (AOP).
Answering to #thewhiteambit on some comment...
#thewhiteambit said:
Exceptions are not Fatal-Errors, they are Exceptions! Sometimes they
are not even Errors, but to consider them Fatal-Errors is completely
false understanding of what Exceptions are.
First of all, how an exception can't be even an error?
No database connection => exception.
Invalid string format to parse to some type => exception
Trying to parse JSON and while input isn't actually JSON => exception
Argument null while object was expected => exception
Some library has a bug => throws an unexpected exception
There's a socket connection and it gets disconnected. Then you try to send a message => exception
...
We might list 1k cases of when an exception is thrown, and after all, any of the possible cases will be an error.
An exception is an error, because at the end of the day it is an object which collects diagnostic information -- it has a message and it happens when something goes wrong.
No one would throw an exception when there's no exceptional case. Exceptions should be blocking errors because once they're thrown, if you don't try to fall into the use try/catch and exceptions to implement control flow they mean your application/service will stop the operation that entered into an exceptional case.
Also, I suggest everyone to check the fail-fast paradigm published by Martin Fowler (and written by Jim Shore). This is how I always understood how to handle exceptions, even before I got to this document some time ago.
[...] consider them Fatal-Errors is completely false understanding of what exceptions are.
Usually exceptions cut some operation flow and they're handled to convert them to human-understandable errors. Thus, it seems like an exception actually is a better paradigm to handle error cases and work on them to avoid an application/service complete crash and notify the user/consumer that something went wrong.
More answers about #thewhiteambit concerns
For example in case of a missing Database-Connection the program could
exceptionally continue with writing to a local file and send the
changes to the Database once it is available again. Your invalid
String-To-Number casting could be tried to parse again with
language-local interpretation on Exception, like as you try default
English language to Parse("1,5") fails and you try it with German
interpretation again which is completely fine because we use comma
instead of point as separator. You see these Exceptions must not even
be blocking, they only need some Exception-handling.
If your app might work offline without persisting data to database, you shouldn't use exceptions, as implementing control flow using try/catch is considered as an anti-pattern. Offline work is a possible use case, so you implement control flow to check if database is accessible or not, you don't wait until it's unreachable.
The parsing thing is also an expected case (not EXCEPTIONAL CASE). If you expect this, you don't use exceptions to do control flow!. You get some metadata from the user to know what his/her culture is and you use formatters for this! .NET supports this and other environments too, and an exception because number formatting must be avoided if you expect a culture-specific usage of your application/service.
An unhandled Exception usually becomes an Error, but Exceptions itself
are not codeproject.com/Articles/15921/Not-All-Exceptions-Are-Errors
This article is just an opinion or a point of view of the author.
Since Wikipedia can be also just the opinion of articule author(s), I wouldn't say it's the dogma, but check what Coding by exception article says somewhere in some paragraph:
[...] Using these exceptions to handle specific errors that arise to
continue the program is called coding by exception. This anti-pattern can quickly degrade software in performance and maintainability.
It also says somewhere:
Incorrect exception usage
Often coding by exception can lead to further issues in the software
with incorrect exception usage. In addition to using exception
handling for a unique problem, incorrect exception usage takes this
further by executing code even after the exception is raised. This
poor programming method resembles the goto method in many software
languages but only occurs after a problem in the software is detected.
Honestly, I believe that software can't be developed don't taking use cases seriously. If you know that...
Your database can go offline...
Some file can be locked...
Some formatting might be not supported...
Some domain validation might fail...
Your app should work in offline mode...
whatever use case...
...you won't use exceptions for that. You would support these use cases using regular control flow.
And if some unexpected use case isn't covered, your code will fail fast, because it'll throw an exception. Right, because an exception is an exceptional case.
In the other hand, and finally, sometimes you cover exceptional cases throwing expected exceptions, but you don't throw them to implement control flow. You do it because you want to notify upper layers that you don't support some use case or your code fails to work with some given arguments or environment data/properties.
The only time you should worry your users about something that happened in the code is if there is something they can or need to do to avoid the issue. If they can change data on a form, push a button or change a application setting in order to avoid the issue then let them know. But warnings or errors that the user has no ability to avoid just makes them lose confidence in your product.
Exceptions and Logs are for you, the developer, not your end user. Understanding the right thing to do when you catch each exception is far better than just applying some golden rule or rely on an application-wide safety net.
Mindless coding is the ONLY kind of wrong coding. The fact that you feel there is something better that can be done in those situations shows that you are invested in good coding, but avoid trying to stamp some generic rule in these situations and understand the reason for something to throw in the first place and what you can do to recover from it.
I know this is an old question, but nobody here mentioned the MSDN article, and it was the document that actually cleared it up for me, MSDN has a very good document on this, you should catch exceptions when the following conditions are true:
You have a good understanding of why the exception might be thrown, and you can implement a specific recovery, such as prompting the user to enter a new file name when you catch a FileNotFoundException object.
You can create and throw a new, more specific exception.
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch(System.IndexOutOfRangeException e)
{
throw new System.ArgumentOutOfRangeException(
"Parameter index is out of range.");
}
}
You want to partially handle an exception before passing it on for additional handling. In the following example, a catch block is used to add an entry to an error log before re-throwing the exception.
try
{
// Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
// Call a custom error logging procedure.
LogError(e);
// Re-throw the error.
throw;
}
I'd suggest reading the entire "Exceptions and Exception Handling" section and also Best Practices for Exceptions.
The better approach is the second one (the one in which you specify the exception type). The advantage of this is that you know that this type of exception can occur in your code. You are handling this type of exception and you can resume. If any other exception came, then that means something is wrong which will help you find bugs in your code. The application will eventually crash, but you will come to know that there is something you missed (bug) which needs to be fixed.
With Exceptions, I try the following:
First, I catch special types of exceptions like division by zero, IO operations, and so on and write code according to that. For example, a division by zero, depending the provenience of the values I could alert the user (example a simple calculator in that in a middle calculation (not the arguments) arrives in a division by zero) or to silently treat that exception, logging it and continue processing.
Then I try to catch the remaining exceptions and log them. If possible allow the execution of code, otherwise alert the user that a error happened and ask them to mail a error report.
In code, something like this:
try{
//Some code here
}
catch(DivideByZeroException dz){
AlerUserDivideByZerohappened();
}
catch(Exception e){
treatGeneralException(e);
}
finally{
//if a IO operation here i close the hanging handlers for example
}
The second approach is a good one.
If you don't want to show the error and confuse the user of application by showing runtime exception(i.e. error) which is not related to them, then just log error and the technical team can look for the issue and resolve it.
try
{
//do some work
}
catch(Exception exception)
{
WriteException2LogFile(exception);//it will write the or log the error in a text file
}
I recommend that you go for the second approach for your whole application.
Leave blank catch block is the worse thing to do. If there is an error the best way to handle it is to:
Log it into file\database etc..
Try to fix it on the fly (maybe trying alternative way of doing that operation)
If we cannot fix that, notify the user that there is some error and of course abort the operation
To me, handling exception can be seen as business rule. Obviously, the first approach is unacceptable. The second one is better one and it might be 100% correct way IF the context says so. Now, for example, you are developing an Outlook Addin. If you addin throws unhandled exception, the outlook user might now know it since the outlook will not destroy itself because of one plugin failed. And you have hard time to figure out what went wrong. Therefore, the second approach in this case, to me, it is a correct one. Beside logging the exception, you might decide to display error message to user - i consider it as a business rule.
Best practice is to throw an Exception when the error occurs. Because an error has occurred and it should not be hidden.
But in real life you can have several situations when you want to hide this
You rely on third party component and you want to continue the program in case of error.
You have a business case that you need to continue in case of error
You should consider these Design Guidelines for Exceptions
Exception Throwing
Using Standard Exception Types
Exceptions and Performance
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions
The catch without any arguments is simply eating the exception and is of no use. What if a fatal error occurs? There's no way to know what happened if you use catch without argument.
A catch statement should catch more specific Exceptions like FileNotFoundException and then at the very end you should catch Exception which would catch any other exception and log them.
Sometimes you need to treat exceptions which say nothing to users.
My way is:
To catch uncaughted exceptions on application level (ie. in global.asax) for critical exceptions (application can not be useful). These exeptions I am not catching on the place. Just log them on app level and let system do its job.
Catch "on place" and show some useful info to user (entered wrong number, can't parse).
Catch on place and do nothing on marginal problems like "I will check for update info on the background, but the service is not running".
It definitely does not have to be best practice. ;-)
I can tell you something:
Snippet #1 is not acceptable because it's ignoring exception. (it's swallowing it like nothing happened).
So do not add catch block that do nothing or just rethrows.
Catch block should add some value. For example output message to end user or log error.
Do not use exception for normal flow program logic. For example:
e.g input validation. <- This is not valid exceptional situation, rather you should write method IsValid(myInput); to check whether input item is valid or not.
Design code to avoid exception. For example:
int Parse(string input);
If we pass value that cannot be parsed to int, this method would throw and exception, instead of that we might write something like this:
bool TryParse(string input,out int result); <- this method would return boolean indicating if parse was successfull.
Maybe this is little bit out of scope of this question, but I hope this will help you to make right decisions when it's about try {} catch(){} and exceptions.

Exiting a Class From C# Using a Catch

I'm looking for the best method of handling errors in a c# winforms class that I have. The gist of the application is that it has a data analyzer that analyzes the data for statistics and other such stuff. However, I'm looking for the proper way of handling an ABORT.
For example, I have the class called Analyzer
namespace PHOEBE
{
public class Analyzer
{
public Analyzer(){
DoAnalysis();
DoFurtherAnalysis();
}
public class DoAnalysis(){
try{
Convert.ToInt32("someNumber...."); //obviously fails..
}
catch{
//ERROR OCCURRED, ABORT ALL ANALYSIS
return;
}
}
}
Obviously, when DoAnalysis() is called, there will be an error that occurs. The catch block will catch the exception. However, when this catch occurs, it will return to the constructor and run DoFurtherAnalysis(). This is a problem.
I know that you could do return values from each method where each value indicates a certain outcome (ie. 1 = success, 0 = fail). However, a lot of the methods I call, use return values already. I could also use a boolean that gets flagged when an error occurs and check that value before calling the next method from the constructor, but checking this value each time is annoying and repetitive.
I was really hoping for some sort of like "abort mechanism" that I could use. Is there any other ways of working around this? Any interesting work-arounds for this?
Assume this class is being called from a form.
Just let the exception propagate up - you should only catch the exception if you can actually handle it. Exceptions are the "abort mechanism" in .NET. You're currently swallowing the signal that everything's gone wrong, and returning as if all were well.
Generally I find catching exceptions to be pretty rare - usually it's either at the top level (to stop a whole server from going down just because of one request) or in order to transform an exception of one kind into another in order to maintain appropriate abstractions.
I was really hoping for some sort of like "abort mechanism" that I
could use. Is there any other ways of working around this? Any
interesting work-arounds for this?
Yes, there is. It is called exception handling.
Let's rewrite your code:
namespace PHOEBE
{
public class Analyzer
{
public Analyzer()
{
try
{
DoAnalysis();
DoFurtherAnalysis();
}
catch
{
//ERROR OCCURRED, ABORT ALL ANALYSIS
return;
}
}
public class DoAnalysis()
{
Convert.ToInt32("someNumber...."); //obviously fails..
}
}
Now, the constructor will abort and not run the second method since the exception will "bubble through" and be catched where you want it.
On an unrelated note: Please try to catch as specific exceptions as possible, in this case a FormatException
You are subverting the existing "abort" mechanism by catching an exception that you are not doing anything about and swallowing it.
You should not use a try{}catch{} block in this case and let the exception bubble up and cause the application to abort.
The easiest work-around is don't catch the exception. If that were to happen, it'd go straight past the DoFurtherAnalysis() function and out to the original caller.
Don't see anything anoying in returning and checking bool return value from the function. It's much much better solution then having some tricky internal state management, that you for sure will messed up after a couple of months when you return to your code.
Make code sumple and streghtforward. It's not anoying, it's good.
In your specific case if you want just abort everything, just do not catch exception it will abort your program.
use a try...catch in the constructor?
Well, you've got several issues mixed up here. First, it looks like you do possibly-very expensive processing from your constructor. If that processing can throw, you really don't want to call it from your constructor becuase you don't even have the option of returning an error code.
Second, (and you'll read in many threads here,) how you handlee errors really depends on the application and expectation of your users. Some errors could be corrected by changes to inputs. Others might happen in the middle of the night if analysis takes a long time and you might want to continue with another analysis, logging this error.
So I think we're really going to punt back to you for more information about the above.
You could just move DoFurtherAnalysis(); into the the try block
And I would do this entire process somewhere other than the constructor.
Only thing I ever do in the constructor is initialize properties.

Is it always a bad practice to catch System.Exception?

Please consider the following piece of code, which throws three different exceptions (namely, System.Configuration.ConfigurationErrorsException, System.FormatException and System.OverflowException):
int SomeInt = Convert.ToInt32(ConfigurationManager.AppSettings["SomeIntValue"]);
The exceptions are different, and so in practice I should have three different catch blocks to handle each particular exception. However, in this particular case, all exceptions are handled the same way: a log is written to, say, EventViewer, and a message informing of a configuration error is displayed... In this particular cause, is it too bad to use
try
{
int SomeInt = ConfigurationManager.AppSettings["SomeIntValue"];
}
catch (Exception ThisException)
{
/* Log and display error message. */
}
or should I, instead, use the three catch blocks and repeat the code within each of them?
See C# Exception Handling Fall Through for a discussion around this problem.
In short, if you catch the general Exception you should check if it is one of the expected types and if not rethrow it.
Update(and a bit out of scope)
Also there are a few times I think it's valid to do a catch all. This is very rare but sometimes in webservices or if you do something on the background thread in asp.net as and exception there will restart the whole application and people might lose their session if you have taken a dependency on that.
It is bad practice to catch System.Exception . . . or better yet, it is bad practice to handle System.Exception anywhere but the top level of your application. What you should to is:
Catch System.Exception
Test the exception for the types you plan to handle identically
Rethrow if it's not one of those.
Example code:
catch (Exception ex)
{
if (ex is FormatException || ex is OverflowException || ex is ConfigurationErrorsException) {
CommonHandler();
}
else {
throw;
}
}
I don't think it's bad practice. If your desired functionality is "whenever this code throws an exception, then take these actions" then I think catching System.Exception is perfectly appropriate.
The fact that you're wrapping a very specific framework function instead of a large block of custom code helps in my opinion as well.
What is really needed, but the .net exception hierarchy doesn't provide, is a clean way of distinguishing exceptions which mean "The requested operation didn't happen, but the system state is essentially fine except to the extent implied by the operation not having happened" from those which mean "The CPU is on fire, and even trying to save the current user's work would likely as not make things worse." There are a lot of contexts in which one really should endeavor to catch all exceptions of the first type, while ideally not catching those of the second. While there a few gradations beyond the two above, generally when catching exceptions one doesn't really care about the distinction between an InvalidArgumentException or an InvalidOperationException; what one cares about is whether the overall system state is valid or corrupted.
As it is, if one is making a call to e.g. a file-import plug-in and it throws an exception, I'm not really sure one can do except try to catch and rethrow really bad exceptions, while having all other exceptions put up a "This file could not be opened" dialog box. Hopefully the state of the system at that point is essentially as it would be had the user not tried to open the file, but without some standardized way of indicating exception severity, I don't think there's any way to be sure.
Incidentally, if I had my druthers, there would be a class ExceptionBase, from which all exceptions would derive; most exceptions would derive from Exception (which would in turn derive from ExceptionBase) but things like ThreadAbortException, StackOverflowException, OutOfMemoryException, etc. would be derived from CriticalException. That way one could catch most 'unexpected' exceptions without accidentally stifling the really bad ones.
It is not necessarily bad practice, the bad practice usually occurs when you do silly things in the catch block. Catching the base exception class is a good safety measure assuming you need to do something when the error occurs. The case for catching a specific exception class is best manifest when that specific class gives you information you can act on, catching SqlException for example can help you look at certain properties specific to that class and let you act on the problem.
Often times people will catch an exception and do something silly like create a new exception or even worse, swallow the exception details.
An often missed pattern is that you can catch, act an rethrow.
catch(Exception ex)
{
//do something
throw;
}
thus preserving the exception details.
In this particular case, it is entirely possible to use different catch blocks, as you do have different actions you can take depending on what exception you get.
For the first two you can set a reasonable default silently as to not annoy the user needlessly, then hope the problem fixes itself when you save your file, and for the latter exception you can ask the user if he wants to continue with the loading process (in which case you set a reasonable default), since the configuration file is obviously corrupted.
In general, the thinking is this: Do I need to take different actions in regards to different kinds of exceptions being thrown? More often than not, the answer is no, so a blank catch(Exception ex){ /* log... */ } (or even no catch at all if the exception is invariably fatal) is enough.
Edit: Blank as in blank check, not empty block :)

Categories