Related
I want to add column from one table to another.
Here, colName is string variable, which is extracted from hard-coded parameter provided by developer.
so chances of colName being incorrect is very less.
I want to avoid exception raised due to wrong colName.
Which is the best way to achieve same?
I thought of two options below.
if(_table.Columns.Contains(colName))
{
AddColumnToTable(_table.Columns[colName]);
}
OR
try
{
AddColumnToTable(_table.Columns[colName]);
}
catch { }
First of all, the whole world died a little inside when this happened:
catch { }
But I digress...
The real question isn't whether you should use if vs. try, the real question is:
If the column can't be added, then what?
If this is an expected scenario and basically "not a big deal" and the logic can continue just fine without adding the column, then if is definitely the way to go. As mentioned in a comment on the question, "test and then act".
If, however, this is not an expected scenario and it "is a big deal" and the logic can't meaningfully continue, throw an exception. Don't catch it and ignore it. Let the consuming code (at the application level) catch it and handle it, likely notifying a user or logging the error or perhaps even attempting to correct it in some way.
(Or if this code is at the application level, catch it here and handle it. The point being that handling is different from catching. The latter is a simple catch block, the former is the custom logic required to respond to the error in a meaningful way.)
You can even add further information to the exception. For example:
try
{
// perform some operation
}
catch (SpecificException ex)
{
throw new CustomException("Failed to perform Operation X in the context of Y.", ex);
}
This can be very valuable when diagnosing a production system where you can't attach a debugger. Specific exception types, helpful error messages, and of course the technical details of the original exception are all necessary tools.
Based solely on the information you provide there is only one conclusion :
if(_table.Columns.Contains(colName))
{
AddColumnToTable(_table.Columns[colName]);
}
because the alternative is an exception handling with an empty catch block. This basically means that it really IS your intent not to do anything with the condition that the colName is not found.
However if your code is stripped down to an arbitrary example and you just cleared the catch block to make the post more condense, the conclusion might be different.
Doing this :
catch { }
Should anyhow be avoided.
Based on this statement :
Here, colName is string variable, which is extracted from hard-coded parameter provided by developer.
You could opt to include an assertion in your code instead of an exception because passing the wrong column name can be considered an application bug.
Because you don't really want to foresee an exception I think an assert is quite a good alternative. That would yield following code :
if(_table.Columns.Contains(colName))
{
AddColumnToTable(_table.Columns[colName]);
}
else Debug.Assert(false,"Column name is wrong, please correct calling code.");
or more condense :
Debug.Assert(_table.Columns.Contains(colName),
"Column name is wrong, please correct calling code.");
AddColumnToTable(_table.Columns[colName]);
Never use try/catch if you can use if. It's the matter of code readability and maintainability.
If you value performance, however, you might consider possibility of failure in this scenario. Your library might do something like this:
void AddColumn(string columnName, Column column)
{
if(this.Columns.Contains(columnName))
throw new DuplicateColumnException();
else
this.Columns.Add(columnName, column);
}
Which would mean that your if would add second Contains invocation and depending on its complexity throwing an exception might be better than invoking second check.
The best way to resolve this would be finding the method that sets the column:
void SetColumn(string columnName, Column column)
{
if(this.Columns.Contains(columnName))
this.Columns[columnName] = column;
this.Columns.Add(columnName, column);
}
or simply:
void SetColumn(string columnName, Column column)
{
this.Columns[columnName] = column;
}
In the past I have written games in which performance is incredibly important. I found that in cases where the "catch" statement was being hit, there was a serious performance impact. Things were really slow. i guess this is because it has to capture all details about what went wrong and try and output that in the catch statement, all very inefficient stuff. I would try and avoid using a try statement wherever you can. It is always best to do an if statement to capture this sort of thing, especially if performance is important.
I have a complicated programs which iterate over a bunch of input files does a lot of parsing and calculations and then outputs several other files.
void ParseFiles(string[] files, ProcessingDescription description) {
foreach(string file in files) {
try {
DoComplicatedProcessing(file, description);
}
catch(Exception e) {
LogFailure(file, e);
}
}
DisplayResult();
}
My reason for catching System.Exception in this case is that this could fail for a number of reasons, bugs in the parsing/calculation, illegal values in the input files, permission problems even out-of-memory errors if my assumption that all necessary data could fit in memory turns out to be false.
But in the end I don't care why it failed. If the program fails for a specific file I want it to log that failure and continue with the next file.
At the end of the session a user might come back and see which files failed and what error message was thrown, sure in many cases the error message might not help the user but it's better than the program crashing on the first bad file.
I keep hearing "Never catch System.Exception" but I can't really see any other way of doing this.
You should catch only those exceptions, which you could handle. In this case you can handle any exception, thus there is nothing wrong with this code.
Personally, I don't see anything wrong with this. You have clearly thought about the problem and have a solution that fits. Any time someone says "Never ..." in software development there is usually a situation were the reverse is true. I guess that is why others say things like, "It is best practice to ..." and "Usually ...". :)
If you are aware that by catching Exception you will loose granularity of the exception and that you might encounter strange edge cases (memory etc), then it is up to you whether you take on the risk.
Seems to me this is a perfectly reasonable case where catching Exception makes sense, because it accomplishes what you need in your problem space. I get very cautious of universal rules like "Never do this, always do that..." A little bit of flexibility and common sense in those rules sure helps me. I think your code is just fine.
In general, I prefer not to throw exceptions (unless the application processing is forced to stop) since they cause a performance overhead. This MSDN article gives a good overview.
Based on how complicated your processing and since you only want to log failures, I would evaluate adding more 'sanity checks' wherever possible. Something like this:
void ParseFiles(string[] files, ProcessingDescription description) {
foreach(string file in files) {
if(!file.IsValid()) { //uses an extension method
LogFailure(file, "Your Message"); //use the appropriate API
continue;
}
try {
DoComplicatedProcessing(file, description);
}
catch(Exception e) {
LogFailure(file, e);
}
}
DisplayResult();
}
It is good form for your application to meet the requirements of solving the problem you are trying to solve, and if it is expedient and functionally correct to do it the way you're doing it, then do it.
Absolutes ignore context, and there is no such thing as best-practice -- only "best practice for this period of time for our context."
I got the question:
"What do you prefer, exception handling or if-condition?"
for an interview. My answer was that exception handlers are preferred only for exceptional circumstances like a disk permission error on file write. The interviewer seemed to be expecting some other answer. What is the correct answer?
EDIT: Any particular example where exception handling is commonly used when an if-condition would have been more appropriate?
As this question is tagged "C#", we can refer to the .NET Framework Design Guidelines as a good starting point for answering these types of questions. This is the guidance given on MSDN under "Exception Throwing":
Do not use exceptions for normal flow of control, if possible. Except
for system failures and operations with potential race conditions,
framework designers should design APIs so that users can write code
that does not throw exceptions. For example, you can provide a way to
check preconditions before calling a member so that users can write
code that does not throw exceptions.
Here is an example of a bad practice where an exception is handled but can nearly always be avoided:
public int? GetItem(int index)
{
int? value = null;
try
{
value = this.array[index];
}
catch (IndexOutOfRangeException)
{
}
return value;
}
This seems contrived but I see code like this quite often from newer programmers. Assuming proper synchronization around reads and writes to array, this exception can be 100% deterministically avoided. Given that, a better way to write that code would be the following:
public int? GetItem(int index)
{
int? value = null;
// Ensure the index is within range in the first place!
if (index >= 0 && index < this.array.Length)
{
value = this.array[index];
}
return value;
}
There are other cases where you cannot reasonably avoid exceptions and just need to handle them. This is most commonly encountered when you have to deal with external resources such as files or network connections which you could potentially lose access to or contact with at any time. Example from WCF:
public void Close()
{
// Attempt to avoid exception by doing initial state check
if (this.channel.State == CommunicationState.Opened)
{
try
{
// Now we must do a (potentially) remote call;
// this could always throw.
this.channel.Close();
}
catch (CommunicationException)
{
}
catch (TimeoutException)
{
}
}
// If Close failed, we might need to do final cleanup here.
if (this.channel.State == CommunicationState.Faulted)
{
// local cleanup -- never throws (aside from catastrophic situations)
this.channel.Abort();
}
}
Even in the above example, it's good to check that the operation you are going to do at least has a chance of succeeding. So there is still an if () check, followed by the appropriate exception handling logic.
Exception handling is a heavy and expensive operation as far as performance is concerned. If you can avoid catching an exception by using proper if else that can increase application's performance
On the other hand if else block makes more sense to code reader. They are easy to understand and maintain as compared to exceptional try catch block. They describe the program flow in more elegant manner
And finally as you said Exception handling should be for uncertain situations or for exceptional cases it should not be the default choice
Edit
A common bad practise I have seen at some places is this
try
{
string str = "Some String"
int i = Convert.ToInt32(str);
}
catch (Exception ex)
{
MessageBox.Show("Invalid input");
}
Now try catch can be easily avoided in this casing by using if else
string str = "Some String"
int i;
if(!int.TryParse(str, out i))
{
MessageBox.Show("Invalid input");
}
The correct answer is just the one that you gave.
For greater specificity, you should've said something to the effect of "I use if statements wherever possible due to the overhead of catching and throwing exceptions".
I normally prefer to use some special undefined value (e.g. null for objects) to indicate that some computation could not produce a valid result because of invalid input. This means that my code could successfully determine and report that the input data is invalid and no meaningful result can be produced.
I prefer to use an exception when my code cannot complete the requested computation, e.g. if a file containing some required data does not exist, if it cannot connect to a database.
So conceptually:
Undefined result (plus if-condition): program successfully determines that there is no valid output for the given input.
Exception (plus try-catch): program cannot complete computation due to some error in the application not related to the input.
If you know the exact login of the program and knows the errors that can occur then you can write if-else statement or in other case you can leave things to try catch exception handling.
So I am recently writing a relatively complex application written in C# that performs an array of small tasks repeatedly. When I first started the application I realized that a lot of the code I was typing was repetitive and so I began encapsulating the majority of the app's logic into separate helper classes that I could call as needed.
Needless to say the size of my app (and amount of code) was cut in half. But as I was going through I noticed something else in my application that seemed to be repetitive and looked like it could be improved.
Now most of my methods in my helper classes are either making a HttpWebRequest or performing save/delete operations on files. Having said that I need to handle the possibility that eventually the call won't complete, or the file can't save because there isn't enough space, or whatever. The problem I'm running into is that I have to keep writing try/catch statements every time I call one of the methods. On top of that I have to retype the error message (or Eventually a status message. I would like to know when it succeeds as well).
So here's kind of a snippet of what I have to type:
try
{
ItemManager.SaveTextPost(myPostItem);
}
// Majority of the time there is more than one catch!
catch
{
//^^^Not to mention that I have to handle multiple types of exceptions
//in order to log them correctly(more catches..ugh!)
MessageBox.Show("There was an error saving the post.");
//Perform logging here as well
}
From what I have concluded so far is:
To me this is overkill having to write this over 50 times for my app.
Sounds like I should be including this in the helper class and
include the full set of catches.
But how could I know the result? I was maybe thinking of returning a
string that contains the error/success message.
Really for these types of methods it doesn't require the method from which the helper method is being called from to enclose it in a try/catch block.
Is this approach correct? Is there another way of doing this? Should I be using a try/catch in the calling method at all? Since this kind of my first shot at this I would really like to hear what others who have handled this scenario have to say.
I think putting the try/catch in the method you are calling is perfectly fine. You can return error/success codes to the calling code in a variety of ways. .NET and c# handle enumerations nicely, so you could have ItemManager.SaveTextPost(myPostItem, out errorCode); where errorCode would be an enumerated value that would let you know if any problems occurred. It could also be as simple as having the method return a bool true if successful, false if otherwise. There are many ways that you could handle that issue, but as far as I'm concerned putting the try/catch in the method is the preferable way of doing things.
AOP libraries like PostSharp are designed to handle cross-cutting concerns exactly like this.
If all these helper methods employ the same boilerplate try catch -> handle multiple types of exceptions, then you can write one aspect that does that, and decorate all of the relevant methods with the appropriate attribute.
There is no single perfect rule for exception handling, so the answer is: It depends. In general you should only catch exceptions, if you know how to handle them. In your example my first question would be, if the application can continue to run after this error and would still be in a valid state. If not, you should rethrow the exception after logging. Then think about nesting exception: You can catch an exception, add information by nesting it into another and throwing that exception. If you design your exception classes and handlers carefully, your logging and displaying code should become much simpler than you expect it. But the details obviously depend on your application.
All of these ways are great options. One thing you want not to do is to use a try {} catch {} for flow control. This means something like this (again avoid this)
Void SomeMethod()
{
try
{
while(somecondition)
{
try
{
}
catch (Exception ex)
{
}
}
}
catch (Exception ex)
{
.....
}
Instead you want to code defensively.
You should throw exceptions in your helper methods by checking with if blocks if every argument is correct, every file is reachable... then if needed, implement some try catch blocks in your helper methods and throw exceptions when catching.
Finally, enclose these helper methods by a try catch block, but at this time, really catch the exceptions:
try
{
ItemManager.SaveTextPost(myPostItem);
// SaveTextPost can throw some exceptions (that you know)
}
catch (Exception e)
{
// You know the exceptions that SaveTextPost can return, so threat them
// correctly
if (e is FileNotFoundException)
MessageBox.Show("The file was not found when saving the post.");
else if (e is ArgumentNullException)
MessageBox.Show("The post can't be null to be saved.");
else
MessageBox.Show("There was an error saving the post.");
}
At the end, you need to treat the error and show an error message to the user. You only can decide if the MessageBox.Show should be implemented in the helper method or in the class calling the helper method.
Personally, I think helper methods are destined to be used by any developer that will run your code, so you should let him decide what he wants to do with the error. That means throwing exceptions in the helper method.
Try/Catch is a good solution. One suggestion, I like to use this to stem the flow of errors: exception catching:
try
{
}
catch (Exception ex)
{
ShowExceptionError(ex);
}
Then I will simply throw all exceptions to a single method, and let the method handle each.
Kind of like this:
private void ShowExceptionError(ex)
{
string errorMessage = "Type of error:" + ex.GetType().ToString();
string stackTrace = ex.StackTrace();
MessageBox.Show(errorMessage + "\n\n" + stackTrace);
}
My personal take on exception handling is.. add try {} catch {} where it makes sense.
For example always use a try catch when calling "untrusted" code, i.e. modules or plugins. otherwise if you are going to catch an exception make sure you can do something meaningful with it. If not, allow the exception to bubble up to a point where you can.
There are few things worse than trying to debug an app where the developer caught an exception and returns a bool. Just sayin'
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.