So far I've learned that (usually) when you assert, you should also throw. At first I wasn't sure it was right, it just made sense1, and then this answer verified.
The problem I have is that it causes repeated-code (at least via contracts). Here's an example of a name field that can't be null or white-space:
public String Name
{
get { return _name; }
set
{
Contract.Requires(String.IsNullOrWhiteSpace(value) == false, "Names cannot be null or whitespace.");
if (String.IsNullOrWhiteSpace(value))
throw new ArgumentException("Names cannot be null or whitespace.");
_name = value;
}
}
Clearly both the condition, and the error message are repeated.
How should I handle it? In one property it's manageable but in a class with multiple fields it's littering.
Additional Information
I thought of using Contract.Requires<TException> (which would assert in debug and throw in release), but the condition (which is the code) would be the message of the exception, which would most likely be displayed to the user (a user would probably like to know why his program crashed, and I wouldn't want to show the actual code). Here's an example:
static void MyFunction(Boolean youCanSeeMyCode = false)
{
Contract.Requires<Exception>(youCanSeeMyCode, "(This is the exception's message)");
}
...
try
{
MyFunction();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
Any suggestions? I'm at a loss.
1 It made sense because if you only use assert and you still have a bug somewhere that you're unaware of, the release build would carry on as if everything's okay and hell could break loose.
The answer you've linked to is about Debug.Assert, which is turned off for release builds by default. I've never liked that idea - it's like saying that it's only worth wearing a seatbelt when you're learning to drive, but not when you're driving at speed.
I would encourage you to just use Contract.Requires (no separate explicit throw statement) and then make sure that you configure your project so that preconditions are still checked in release builds. Your concern about the message being displayed to the user isn't a concern which should be addressed here - it should be addressed in your general exception handling. If you don't want to show exception messages to the user, don't show them... but do log them. You really shouldn't try to make exceptions meaningful to end users... that's not their purpose.
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.
This is not so much of a problem but more feedback and thoughts. I have been considering an implementation for methods that have been tested thoroughly through our internal teams. I would like to write a generic exception catch method and reporting service.
I relize this is not as easy as a "try-catch" block, but allows for a uniform method for catching exceptions. Ideally I would like to execute a method, provide a failure callback and log all the parameters from the calling method.
Generic Try-Execute.
public class ExceptionHelper
{
public static T TryExecute<T, TArgs>(Func<TArgs, T> Method, Func<TArgs, T> FailureCallBack, TArgs Args)
{
try
{
return Method(Args);
}
catch (Exception ex)
{
StackTrace stackTrace = new StackTrace();
string method = "Unknown Method";
if (stackTrace != null && stackTrace.FrameCount > 0)
{
var methodInfo = stackTrace.GetFrame(1).GetMethod();
if (methodInfo != null)
method = string.Join(".", methodInfo.ReflectedType.Namespace, methodInfo.ReflectedType.Name, methodInfo.Name);
}
List<string> aStr = new List<string>();
foreach (var prop in typeof(TArgs).GetProperties().Where(x => x.CanRead && x.CanWrite))
{
object propVal = null;
try
{
propVal = prop.GetValue(Args, null);
}
catch
{
propVal = string.Empty;
}
aStr.Add(string.Format("{0}:{1}", prop.Name, propVal.ToString()));
}
string failureString = string.Format("The method '{0}' failed. {1}", method, string.Join(", ", aStr));
//TODO: Log To Internal error system
try
{
return FailureCallBack(Args);
}
catch
{
return default(T);
}
}
}
}
What I know as draw backs.
Performance Loss using reflection
MethodBase (methodInfo) may not be available through optimization
The try-catch around the error handler. Basically I could use the TryExecute wrapper for the try-catch around the error call back however that could result in a stack overflow situation.
Here would be a sample implementation
var model = new { ModelA = "A", ModelB = "B" };
return ExceptionHelper.TryExecute((Model) =>
{
throw new Exception("Testing exception handler");
},
(Model) =>
{
return false;
},
model);
Thoughts and comments appreciated.
That's a lot of code to put in a catch, including two more try/catch blocks. Seems like a bit of overkill if you ask me, with a good amount of risk that a further exception can obscure the actual exception and that the error information would be lost.
Also, why return default(T)? Returning defaults or nulls as indications of a problem is usually pretty sloppy. If nothing else, it requires the same conditional to be wrapped around every call to the method to check for the return and respond to... some error that has gone somewhere else now.
Honestly, that usage example looks pretty messy, too. It looks like you'll end up obscuring the actual business logic with the error-trapping code. The entire codebase will look like a series of error traps, with actual business logic hidden somewhere in the entanglement of it. This takes valuable focus off of the actual intent of the application and puts something of background infrastructure importance (logging) at the forefront.
Simplify.
If an exception occurs within a method, you generally have two sensible options:
Catch (and meaningfully handle) the exception within the method.
Let the exception bubble up the stack to be caught elsewhere.
There's absolutely nothing wrong with an exception escaping the scope of the method in which it occurs. Indeed, exceptions are designed to do exactly that, carrying with them useful stack information about what happened and where. (And, if you add meaningful runtime context to the exception, it can also carry information about why.)
In fact, the compiler even subtly hints at this. Take these two methods for example:
public int Sum(int first, int second)
{
// TODO: Implement this method
}
public int Product(int first, int second)
{
throw new NotImplementedException();
}
One of these methods will compile, one of them will not. The compiler error will state that not all code paths return a value on the former method. But why not the latter? Because throwing an exception is a perfectly acceptable exit strategy for a method. It's how the method gives up on what it's doing (the one thing it should be trying to do and nothing more) and let's the calling code deal with the problem.
The code should read in a way that clearly expresses the business concept being modeled. Error handling is an important infrastructure concept, but it's just that... infrastructure. The code should practically scream the business concept being modeled, clearly and succinctly. Infrastructure concerns shouldn't get in the way of that.
This is very rarely going to be useful.
It covers only cases where:
The method has a well-defined means of obtaining an appropriate return value in the face of failure.
You'd actually care to log that it happened.
Now, 2 is very common with exceptions of all sorts, but not where 1 is true too.
1 of course is rare, since in most cases if you could produce a reasonable return value for given parameters by means X you wouldn't be trying means Y first.
It also has a default behaviour of returning default(T) - so null or all zeros - if the fallback doesn't work.
This only works where your case 1 above has "something that just returns null as a result because we don't really care very much what this thing does", or where the called method never returns null, in which case you then test for null, which means that your real error-handling code happens there.
In all, what you've got here is a way in which exceptions that would be trappable by real code have to be caught for by testing (and sometimes testing + guesswork) instead, and those that would bring down a program in a clear place with nice debugging information will instead put it into a state where you don't know what's going on anywhere, but at least of the few dozen bugs that got logged before something managed to bring it down fully, one of the is probably the actual problem
When you've a catch on some exception for a particular reason, by all means log the exception. Note that this is not so much to help find bugs (if that exception being raised there is a bug, you shouldn't be catching it there), but to cancel out the fact that having a catch there could hide bugs - i.e. to cancel out the very effect you are deliberately encouraging by putting catches all over the place. (E.g. you expect a regularly hit webservice to fail to connect on occasion, and you can go on for some hours with cached data - so you catch the failure and go on from cache - here you log because if there was a bug meaning you were never trying to hit the webservice correctly, you've just hidden it).
It's also reasonable to have some non-interactive (service or server) app log all exceptions that reach the top of the stack, because there's nobody there to note the exception.
But exceptions are not the enemy, they're the messenger. Don't shoot the messenger.
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.
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.
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.