How to handle non-fatal error conditions - c#

I'm not sure if this is a duplicate but if it is please feel free to close this.
Background:
I have a timer component for a game i'm writing that supports Stop and Pause methods. The non-critical error cases in question are doing things like calling Pause when in the timer is already paused, this is not fatal but it's not going to cause the change in state implied by the method name
Questions:
1. How does one generally indicate a non-fatal but abnormal condition?
2. Should I actually be throwing an exception in these cases? I think it's a little heavy-handed considering calling Pause when paused wont do any harm
3. Am I over-thinking this
UPDATE:
Based on the responses and comments here is the statergy I have chosen to take:
In development builds an exception will occur because I consider these bugs and I'd like to catch them and correct them. I can't justify an exception in a release build because these bugs don't corrupt the game state, and I don't think users of the application would appreciate the loss of their hard earned score because I failed to code properly
Thanks for all your responses, this has been very educational for me.

I think your fine to just ignore the call if the timer is already paused. Assuming the method is called Pause() then the client only requires that after the method call that the timer is paused, and exceptions should only be thrown if it won't be; the method doesn't imply any requirement on the current state of the timer.
On the other hand if the method was called ChangeTimerFromRunningToPaused() then that implies that it is only valid to call this on a running timer. Under these circumstances I would expect it to throw an exception informing the client that the timer is not in a valid state to process this method call.

Against the other answers, I would consider throwing an exception. If it would be my code performing the second Pause() call, I might consider my code to be broken if it makes this call where it should not. Maybe I am missing a check like if (Timer.IsRunning) { } and I don't want to hide this bug by silently ignoring the call. Even if the call is triggered by user input - a button click for example - this might be an indication of bad design and I should have a look at it. Maybe the button should be disabled.
The more I think about it, the less situations come to mind where the second call should not be an exception indicating bad calling code. So, yes, I would throw the exception.
UPDATE
In a comment Martin Harris suggest using Debug.Assert() to get the bug during development. I think that this is to weak because you won't get the bug in production code. But of course you don't want to crash an application in production because of this non-fatal error. So we will just catch this exception up the stack and generate a error report and than resume as if nothing happend.
Here are two goo links.
API Design Myth: Exceptions are for "Exceptional Errors"
Coding Horror - Exception-Driven Development

In such cases (moving some state machine to a state on which it already is), I'd just skip the call. Usually, non-fatal errors or warnings should not be thrown as exception, but rather returned as result (which can be ignored or processed, whatever fits the situation best).

No, don't throw an exception, Exceptions are heavy. There's nothing wrong to pause again. I don't see any harm.

This looks similar (though not identical) to one of my questions, perhaps the answers there are helpful for you.

Related

Is this code defensive programming, or bad practice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I have this debate with my colleague about this piece of code:
var y = null;
if (x.parent != null)
y = x.parent.somefield;
My point of view is that in the place where the code is, x.parent should not POSSIBLY be null. And when it is null, we have a serious problem and I want to know it! Hence, the null check should not be there and let the down stream exception happen.
My colleague says this is defensive programming. And the null check makes sure the code doesn't break the application.
My question is, is this defensive programming? Or a bad practice?
Note: the point is not who is right. I'm trying to learn from this example.
It looks like your colleague is misunderstanding "defensive programming" and/or exceptions.
Defensive Programming
Defensive programming is about protecting against certain kinds of errors.
In this case x.parent == null is an error because your method needs to use x.parent.SomeField. And if parent were null, then the value of SomeField would clearly be invalid. Any calculation with or task performed using an invalid value would yield erroneous and unpredictable results.
So you need to protect against this possibility. A very good way to protect is by throwing a NullPointerException if you discover that x.parent == null. The exception will stop you from getting an invalid value from SomeField. It will stop you doing any calculations or performing any tasks with the invalid value. And it will abort all current work up until the the error is suitably resolved.
Note the exception is not the error; an invalid value in parent that is the actual error. The exception is in fact a protection mechanism. Exceptions are a defensive programming technique, they're not something to be avoided.
Since C# already throws an exception, you don't actually have to do anything. In fact it turns out that your colleague's effort "in the name of defensive programming", is actually undoing built-in defensive programming provided by the language.
Exceptions
I've noticed many programmers are unduly paranoid about exceptions. An exception itself isn't an error, it's simply reporting the error.
Your colleague says: "the null check makes sure the code doesn't break the application". This suggests he believes that exceptions break applications. They generally don't "break" an entire application.
Exceptions could break an application if poor exception handling puts the application in an inconsistent state. (But this is even more likely if errors are hidden.) They can also break an application if an exception 'escapes' a thread. (Escaping the main thread obviously implies your program has terminated rather ungracefully. But even escaping a child thread is bad enough that the best option for an operating system is to GPF the application.)
Exceptions will however break (abort) the current operation. And this is something they must do. Because if you code a method called DoSomething which calls DoStep1; an error in DoStep1 means that DoSomething cannot do its job properly. There is no point in going on to call DoStep2.
However, if at some point you can fully resolve a particular error, then by all means: do so. But note the emphasis on "fully resolve"; this doesn't mean just hide the error. Also, just logging the error is usually insufficient to resolve it. It means getting to the point where: if another method calls your method and uses it correctly, the 'resolved error' will not negatively affect the caller's ability to do its job properly. (No matter what that caller may be.)
Perhaps the best example of fully resolving an error is in the main processing loop of an application. Its job is to: wait for a message in the queue, pull the next message off the queue and call appropriate code to process the message. If an exception was raised and not resolved before getting back to the main message loop, it needs to be resolved. Otherwise the exception will escape the main thread and the application will be terminated.
Many languages provide a default exception handler (with a mechanism for the programmer to override/intercept it) in their standard framework. The default handler will usually just show an error message to the user and then swallow the exception.
Why? Because provided you haven't implemented poor exception handling, your program will be in a consistent state. The current message was aborted, and the next message can be processed as if nothing is wrong. You can of course override this handler to:
Write to log file.
Send call-stack information for troubleshooting.
Ignore certain classes of exception. (E.g. Abort could imply you don't even need to tell the user, perhaps because you previously displayed a message.)
etc.
Exception Handling
If you can resolve the error without an exception first being raised, then it is cleaner to do so. However, sometimes the error cannot be resolved where it first appears, or cannot be detected in advance. In these cases an exception should be raised/thrown to report the error, and you resolve it by implementing an exception handler (catch block in C#).
NOTE: Exception handlers server two distinct purposes: First they provide you a place to perform clean-up (or rollback code) specifically because there was an error/exception. Second, they provide a place to resolve an error and to swallow the exception. NB: It's very important in the former case that the exception be re-raised/thrown because it has not been resolved.
In a comment about throwing an exception and handling it, you said: "I wanted to do that but I was told it creates exception handling code everywhere."
This is another misconception. As per the previous side-note you only need exception handling where:
You can resolve an error, in which case you're done.
Or where you need to implement rollback code.
The concern may be due to flawed cause-and-effect analysis. You don't need rollback code just because you're throwing exceptions. There are many other reasons that exceptions can be thrown. Rollback code is required because the method needs to perform clean-up if an error occurs. In other words the exception handling code would be required in any case. This suggests the best defence against excessive exception handling is to design in such a way that the need for clean-up on errors is reduced.
So don't "not throw exceptions" to avoid excessive exception handling. I agree excessive exception handling is bad (see design consideration above). But it is far worse to not rollback when you should because you didn't even know there was an error.
Interesting question. From my point of view, whether or not to include the check is a matter of how well the data is validated, where does it come from and what can happen when the check fails.
"x.parent should not POSSIBLY be null" is a serious assumption. You need to be very sure of it to play safe, of course there is the classic "it will never happen"....... until it happens, that's why I think it's interesting to review the possibilities.
I see two different things to think about.
Where does the data comes from?
If it comes from another method in the same class, or from some related class, since you have more or less full control about it, it's logical to relax your defenses, as you can reasonably assume that it's very unlikely to have bad data to begin with, or if it happens it's reasonably easy to catch the bug early during debugging/testing and even place some unit tests for it.
The opposite case would be if it's data entered by the user, or read from a file, or from a URL, anything external generally speaking. Since you cannot control what the program is dealing with: by all means, validate it as thoroughly as you can before using it in any way, as you're exposed to bogus/missing/incomplete/incorrect/malicious information that may cause problems down the path.
An intermediate case can be when the input comes from another layer/tier within the same system. It's more difficult to decide whether to do a full validation or take it for granted, since it's another piece of internal software, but might be replaced or modified independently at a later time. My preference goes towards validating again when crossing boundaries.
What to do with the validation?
Using an if (as in your sample) to simply skip over some assignment or usage may be fine for some cases. For instance, if the user is entering some data and this just shows a tooltip or other minor info, it's possibly safe to skip. But if the piece of code does something important, that in turn fills some mandatory condition or executes some other process, it's not the right approach as it will cause problems for the next code run. The thing is, when you skip over some code, it must be safe to do so, without any side effects or unwanted consequences, otherwise you would be hiding some error, and that's quite difficult to debug in later development stages.
Abort the current process gracefully is a good choice for early validations, when the failure is totally expected and you know precisely how to respond to it. An example could be a missing required field, the process gets interrupted and a message is shown to the user asking for the missing info. It's not OK to simply ignore the error, but also not serious enough to throw an exception that disrupts the normal program flow. Of course, you may still use an exception, depending on your architecture, but in any case catch it and recover gracefully.
Throw an exception is always a choice when the "impossible" really happened. It's in those cases where you cannot possibly provide a reasonable response for either continuing with some variation or cancel just the current process, it may be due to a bug or bad input somewhere, but the important thing is that you want to know it and have all the details about it, so the best possible way is to make it to blow up as loudly as possible, so that the exception bubbles up and reaches a global handler that interrupts everything, saves to a log file/DB/whatever, sends a crash report to you and finds a way to resume execution, if that's feasible or safe. At least if your app crashes, do so in the most graceful way, and leave traces for further analysis.
As always, it depends on the situation. But just using an if to avoid coding an exception handler is for sure a bad practice. It must always be there, and then some code may rely on it - whether appropriate or not - if it's not critical to fail.
I wouldn't call it defensive programming at all - I'd call it "la la la I can't hear you" programming :) Because the code appears to be effectively ignoring a potential error condition.
Obviously we don't have any idea of what comes next in your code, but since you didn't include an else clause, I can only assume that your code just carries on even in the case that x.parent is actually null.
Bear in mind that "should not possibly be null" and "is absolutely, positively guaranteed to never be null" are not necessarily the same thing; so in that case it could lead to an exception further down the line when you try to de-reference y.
The question is then - what is more acceptable within the context of the problem you are trying to solve (the "domain") and that kind of depends on what you intend to do with ylater on.
If y being null after this code is not a problem (let's say you do a defensive check later on for y!=null) then that's OK - although personally I don't like that style - you end up defensively checking every single de-reference because you can never be quite sure if you're a null reference away from crashing...
If y cannot be null after the code because it will cause an exception or missing data later on, then it's simply a bad idea to continue when you know that an invariant is not correct.
In short, I'd say this is NOT a defensive programming. I agree with those who thinks this code hides the system error instead of exposing and fixing. This code violates the 'fail fast' principle.
This is true if and only if x.parent is a mandatory non-null property (which seems to be obvious from the context.) However, if x.parent is an optional property (i.e. can reasonably have a null value) then this code can be allright depending on your business logic expressed.
I'm always considering usage of empty values (0, "", empty objects) instead of nulls which require tons of irrelevant if statements.
After some years of thinking about this issue, I use the following "defensive" programming style - 95% of my methods return string as a success / failed result.
I return string.Empty for success, and informative text string if failed. While returning the error text, I write it to log at the same time.
public string Divide(int numA, int numB, out double division)
{
division = 0;
if (numB == 0)
return Log.Write(Level.Error, "Divide - numB-[{0}] not valid.", numB);
division = numA / numB;
return string.Empty;
}
Then I use it:
private string Process(int numA, int numB)
{
double division = 0;
string result = string.Empty;
if (!string.IsNullOrEmpty(result = Divide(numA, numB, out divide))
return result;
return SendResult(division);
}
When you have Log monitoring system, it lets the system show go on, but notifies the administration.

Why is catch (Exception) wrong?

I have read several times that using
catch (Exception ex)
{
Logger.LogError(ex);
}
without re throwing is wrong, because you may be hiding exceptions that you don't know about from the rest of the code.
However, I am writing a WCF service and am finding myself doing this in several places in order to ensure that the service does not crash. (SOA states that clients should not know or care about internal service errors since they unaware of the service implementation)
For instance, my service reads data from the file system. Since the file system is unpredictable I am trapping all exceptions from the read code. This might be due to bad data, permission problems, missing files etc etc. The client doesn't care, it just gets a "Data not available" response and the real reason is logged in the service log. I don't care either, I just know there was a problem reading and I don't want to crash.
Now I can understand there may be exceptions thrown unrelated to the file system. eg. maybe I'm out of memory and trying to create a read buffer has thrown an exception. The fact remains however, that the memory problem is still related to the read. I tried to read and was unable to. Maybe there is still enough memory around for the rest of the service to run. Do I rethrow the memory exception and crash the service even though it won't cause a problem for anything else?
I do appreciate the general idea of only catching exceptions you can deal with, but surely if you have an independent piece of code that can fail without affecting anything else, then it's ok to trap any errors generated by that code? Surely it's no different from having an app wide exception handler?
EDIT: To clarify, the catch is not empty, the exception is logged. Bad example code by me, sorry. Have changed now.
I wouldn't say that your service works as expected if there are permission problems on the disk. imho a service returning "Data not available" is even worse than a service returning "Error".
imagine that you are the user of your service. You make a call to it and it returns "No data". You know that you're call is correct, but since you don't get any data you'll assume that the problem is yours and go back investigating. Lots of hours can be spent in this way.
Which is better? Treating the error as an error, or lie to your users?
Update
What the error depends on doesn't really matter. Access problems should be dealt with. A disk that fails sometimes should be mirrored etc etc. SOA puts more responsibilities on you as a developer. Hiding errors doesn't make them go away.
SOA should pass errors. It may not be a detailed error, but it should be enough for the client to understand that the server had a problem. Based on that, the client may try again later on, or just log the error or inform the service desk that a manual action might need to be taken.
If you return "No data", you won't give your users a chance to treat the error as they see fit.
Update2
I do use catch all in my top level. I log exceptions to the event log (which is being monitored).
Your original question didn't have anything in the catch (which it do now). It's fine as long as you remember to monitor that log (so that you can correct those errors).
If you are going to adopt this strategy you are going to make it very hard for deployment teams to work out why the client fails to work. At the minimum log something somewhere.
One of the main issues becomes that you will never know that something went wrong. It isn't only your clients / consumers that have the error hidden from them, it is you as the service developer yourself.
There's absolutely no problem with that code. Make sure the user gets a nice message, like "Data not available due to an internal problem. The issue has been logged and the problem will be dealt with." And everybody's fine.
It's only a problem if you eat and swallow the exception so that nobody in the world will ever fix it.
Exceptions need always to be dealt with, either by writing special code or by just fixing the path that results in the exception. You can't always anticipate all errors, but you can commit to fixing them as soon as you become aware of them.
I believe the idea is to prevent missing errors. Consider this: The service returns fine but is not doing as expected. You have to go and search through event logs, file logs etc. to find a potential error. If you put a trace write in there, you can identify hopefully the cause, but likely the area of hte issue and a timestamp to correlate errors with other logs.
If you use .NET Trace, you can implement in code and not turn it on until required. Then to debug you can turn it on without having to recompile code.
WCF Services can use FaultException to pass exceptions back to the client. I have found this useful when building a WCF n-tier application server.
It's commendable to ensure that your service does not crash, in a production environment. When debugging, you need the application to crash, for obvious reasons.
However, from your explanations, I get the impression that you're catching the exceptions you expect to be thrown, and catch the rest with an empty catch block, meaning you'll never know what happened.
It's correct to catch all exceptions as a last resort, but please log those too, they are no less interesting than those you expected. After catching and logging all exceptions related to network, I/O, security, authentication, timeout, bad data, whatever, log the rest.
In general you can say that every exception occurs in a specific circumstance. For debugging purposes it is usefull to have as much information as possible about the failure so the person who is about to fix the bug know where to look and can fix the code in a minimum amount of time, which save his boss some money.
Besides that, throwing and catching specific exceptions will make your code more readable/understable and easier to maintain. Catching a general exception will fail on this point in every point of view. Therefore, also make sure that, when throwing an exception, that is is well documented (e.g. in XML comments so the caller knows the method can throw the specific exception) and has a clear name on what went wrong. Also include only information in the exception that is directly related to the problem (like id's and such).
In vb.net, a somewhat better approach would be "Catch Ex As Exception When Not IsEvilException(Ex)", where "IsEvilException" is a Boolean function which checks whether Ex is something like OutOfMemoryException, ExecutionEngineException, etc. The semantics of catching and rethrowing an exception are somewhat different from the semantics of leaving an exception uncaught; if a particular "catch" statement would do nothing with the exception except rethrow "as is", it would be better not to catch it in the first place.
Since C# does not allow exception filtering, you're probably stuck with a few not-very-nice choices:
Explicitly catch and rethrow any "evil" types of exceptions, and then use a blanket catch for the rest
Catch all exceptions, rethrow all the evil ones "as-is", and then have your logic handle the rest
Catch all exceptions and have your logic handle them without regard for the evil ones, figuring that if the CPU is on fire it will cause enough other exceptions to be raised elsewhere to bring the program down before persistent data gets corrupted.
One problem with exception handling in both Java and .net is that it binds tightly three concepts which are actually somewhat orthogonal:
What condition or action triggered the exception
Should the exception be acted upon
Should the exception be considered resolved
Note that sometimes an exception will involve two or more types of state corruption (e.g. an attempt was made to update an object from information at a stream, and something goes wrong reading the stream, leaving both the stream and the object being updated in bad states). Code to handle either condition should act upon the exception, but the exception shouldn't be considered resolved until code for both has been run. Unfortunately, there is no standard pattern for coding such behavior. One could add a virtual read-only "Resolved" property to any custom exceptions one implements, and rethrow any such exceptions if "Resolved" returns false, but no existing exceptions will support such a property.
If something is wrong, then it is wrong. It should crash.
You can never assure proper operations if something is crashing in the code. Even if that means that a page/form will always crash as soon as it is visited, you can never assure that things will keep working, or any changes be functionally committed.
And if a data resource crashes and instead returns a resource with 0 entries, the user will just be incredibly confused by something not returning any results when there should be obvious results. Valueable time will be spent by the user trying to find out what (s)he did wrong.
The only times I would recommend catching all exceptions (and logging them, not ignoring them), is if the code that is being ran is from plugins/compiled code from users, or some weird COM library, that you have no control over yourself.

Why are try-catch in main() bad?

Could someone explain to me why it is considered inapropriate to have a try-catch in the main() method to catch any unhandled exceptions?
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception e)
{
MessageBox.Show("General error: " + e.ToString());
}
}
I have the understanding that this is bad practice, but not sure why.
I don't think its necessarily bad practice. There are a few caveats however...
I believe the point of whoever called this "bad practice" was to reinforce the idea that you should be catching exceptions closest to where they occur (i.e. as high up the call stack as possible/appropiate). A blanket exception handler isn't typically a good idea because its drastically reduces the control flow available to you. Coarse-grained exception handling is quite importantly not a reasonable solution to program stability. Unfortunately, many beginner developers think that it is, and take such approaches as this blanket try-catch statement.
Saying this, if you have utilised exception handling properly (in a fine-grained and task-specific manner) in the rest of your program, and handled the errors accordingly there (rather than juist displaying a generic error box), then a general try-catch for all exceptions in the Main method is probably a useful thing to have. One point to note here is that if you're reproducably getting bugs caught in this Main try-catch, then you either have a bug or something is wrong with your localised exception handling.
The primary usage of this try-catch with Main would be purely to prevent your program from crashing in very unusual circumstances, and should do hardly any more than display a (vaguely) user-friendly "fatal error" message to the user, as well as possibly logging the error somewhere and/or submitting a bug report. So to conclude: this method does have its uses, but it must be done with great care, and not for the wrong reasons.
Well, this method will only capture exceptions thrown in your main thread. If you use both the Application.ThreadException and the AppDomian.UnhandledException events instead then you'll be able to catch and log all exceptions.
I don't see how that's bad practice at all.
Letting your program crash with an unhandled exception error isn't going to instill any confidence in your end users.
Maybe someone else could provide a counter view.
Update:
Obviously you'll need to do something useful with the exception.
log it
show the user a dialog stating WHY the application is exiting (in plain text, not a stacktrace)
something else that makes sense in the context of your application.
I don't think that's a bad practice in and of itself. I think the bad practice would be if that was the ONLY try/catch block you had in your application.
In antiquity, placing a try/catch in C++ caused a fairly heavy performance penalty, and placing one around main would mean storing extra stack info for everything, which again was bad for performance.
Now computers are faster, programmers less addicted to performance, and runtimes are better built, so it's not really bad anymore (but still you might pay a little more for it, haven't benchmarked it's effect in years). So it's old folklore like iterating against the grain (compilers actually fix the iteration anyways for you nowadays). In C# it's perfectly fine, but it'd look iffy to someone from 10 years ago.
Any exception which gets to Main() is likely fatal.
If it was something easy, it should have been handled higher up. If it was something beyond your control, like OutOfMemoryException, then the program should crash.
Windows application which crash have a standard way of doing so, they trigger the Windows Error Reporting dialog. (You've likely seen it before). You can sign up to recieve crash data when this happens.
I'm not sure I think its a bad practice. What you want to do is make sure that the exception and the current state of the program when it crashes ends up in the hands of a developer, preferably logged with date, time and the user who was working with it. Basically - you want to make sure that your team has all the information they need to debug the problem, regardless of whether or not the user goes to them about the crash. Remember that many users will not, in fact, contact support if they get a crash.
The bad practice here would be catching the exception, showing a simple "Error" dialog box, and closing the application. In that case, the state of that exception is lost forever.
From a debugging standpoint, this can make life more difficult, as it makes every exception a user handled exception. This changes the debugger's behavior, unless you break on unhandled exceptions, which potentially has other issues.
That being said, I think this is a good practice at release time. In addition, I recommend listening on the AppDomain.UnhandledException and the Application.ThreadException events, as well. This will let you trap even more exceptions (such as some system exceptions that will not be caught in your "global" handler above).
That allows you to log the errors and provide the user with a good, clean message.
Change it to this and it's fine
catch(Exception ex)
{
YourLoggingSystem.LogException(ex);
}
Of course, this line should NEVER be hit as you'll have other exception handlers throughout your code catching things with much more context.
Top-level exception handling is pretty essential, but I'd recommend using:
Application.ThreadException += new ThreadExceptionEventHandler(YourExceptionHandlingMethod);
However, this will only catch exceptions on the GUI thread (much like your try..catch block) - you should use similar code for each new thread you start to handle any unexpected exceptions from them.
More about it here.
You've got the catch-all exception there which will trap everything. So if you've got any unhandled exceptions in you code you'll never see them.
On the positive side, your application will never crash!
If this is required behaviour then you'll need to have sufficient logging and reporting to let both the user and you, as developer, know what's happened and recover or exit as gracefully as possible.
I'm not saying it's bad practice, the only thing I would do different though is use the built in event for that:
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message); //or do whatever...
}
I think this is discouraged because exceptions are caught only once and there may be multiple things, like background threads, that need to know if a process throws.
Is this a WinForms app? Forms.Application.Run raises events whenever a thread throws an unhandled exception. The MSDN docs try to explain this, but the handler they show doesn't work! Read the updated example from the WinForms UE site.
If your program tries to keep running despite a catch-all catching who-knows-what kind of violation of assumptions down below, it's in a danger zone for things like remote exploitation of security flaws (buffer overflows, heap corruption). Putting it in a loop and continuing to run is a big red flag for software quality.
Getting out as quickly as possible is the best, e.g. exit(1). Log and exit is good though slightly riskier.
Don't believe me? The Mitre Common Weakness Enumeration (CWE) agrees. Closely related is its advice against catching NULL pointer dereferencing in this way.

All About Exceptions: What to do and Where to log?

My question actually comes in two parts hence the ambiguous title.
Part One
As far as I'm aware, you should never swallow an exception. Not even logging it and forgetting about. In general cases, I try to solve an exception and retry the code - for example, let's say I get a FileNotFound exception.
I prompt the user to check the file exists and try again, offering another file chooser dialog and hoping for the best. Failing attempting to solve the problem I end up notifying the user and logging the exception. I've been told that this isn't the correct thing to do in a catch block, so am I doing it right by attempting to solve the issue?
I can't think what else I should do. I suspect I'm being fed misinformation - I'm a gullable soul.
Part Two
Creating a log in my program directory to log an exception is fine I think, but again I'm being told that exceptions should be written to the windows eventlog. Is this correct? Under what circumstances should you write to the event log?
Silly questions need silly answers.
Edit:
There is no context to this question other than a general vague domain. My friend and I were blabbering about the right things to do in particular circumstances.
First off if you ever hear the word Never your ears should perk up... That is why they are called "Best Practices" and not "Rules written in Stone that you must follow..."
here is Microsoft's Exception Handling Best Practices Guide
And there are going to be plenty others...
It really boils down to you as a developer, your teams standards, your customer, etc. What do you want the application to do?
Question 1: Do you want the application to be able to continue on if an exception it thrown? Then I would "swallow" the exception.
Question 2: Is there a benefit to logging a particular exception to the event log or is it just going to bloat it with useless information, You may want to write every exception to the log during development and testing and have verbose information and then in production streamline it... I hope I have answered your question even though there really isn't an generic one...
I would say you should have some general guidelines and then if you have more specific situations then it would be a good time to re-post to this site and get some feedback from people that have tried different routes and can speak to the pros and cons.
The Code Analysis Team Blog is a great place to start on this topic. Also look at
Martin Fowler - Fail Fast
MSDN on Exception Handling
Checked vs Unchecked Exceptions
The second part of your question really depends. In many applications where you need central exception reporting, writing to the event log is a good idea. There are plenty of other cases where it would be a waste of time to do that, you'll have to use your own judgment on that.
Part One
Generally, you don't want to have exception generating behaviour in a catch block.
try
{
ExceptionThrowingMethod();
}
Catch(Exception ex)
{
//Log It
//Try Again
ExceptionThrowingMethod();
}
Clearly, the second exception will be uncaught, and you generally don't want to have try-catches nested within a catch-block.
Generally your catch block should
Log the error. Always. Even if you set it to your lowest logging level, and never read those logs.
Determine whether your current state is recoverable. (Are the right variables set or null? Did it break during a critical function, or between them?)
If you can recover, set some variables that indicate 'try-again', and allow execution to flow OUT of the catch-block. If you cannot recover, try to add some context, and then re-throw the error.
Catch blocks are for error recovery, not for regular execution. So, even through FileNotFound is an exceptional occurrence, prompting the user to try and locate their file is not, and so it should happen in its own try-catch (or loop back to the initial one).
Part Two
Generally, I would prefer writing logs to their own directory, because that way I know exactly where they are, and I also know that everything in the log is relevant. If your application is a critical application, (I.E. a service that needs to be running for a framework to work) then you might consider logging to the eventviewer. There's also the everybody wins method of logging to both. You could have thorough logs in your program directory, and log any critical errors to your event viewer.
Without knowing what reason you were given to log to the event viewer, I can't tell whether or not it's good advice.
Here are some best-practices for exception handling.
Best practices for exception management in Java or C#
I found this to answer part two of my question and it seems from a bit of further research that logging exceptions to the event log isn't a mysterious and dark practice. Thanks for your help everyone.

What is Environment.FailFast?

What is Environment.FailFast?
How is it useful?
It is used to kill an application. It's a static method that will instantly kill an application without being caught by any exception blocks.
Environment.FastFail(String) can
actually be a great debugging tool.
For example, say you have an
application that is just downright
giving you some weird output. You have
no idea why. You know it's wrong, but
there are just no exceptions bubbling
to the surface to help you out. Well,
if you have access to Visual Studio
2005's Debug->Exceptions... menu item,
you can actually tell Visual Studio to
allow you to see those first chance
exceptions. If you don't have that,
however you can put
Environment.FastFail(String) in an
exception, and use deductive reasoning
and process of elimination to find out
where your problem in.
Reference
It also creates a dump and event viewer entry, which might be useful.
It's a way to immediately exit your application without throwing an exception.
Documentation is here.
Might be useful in some security or data-critical contexts.
Failfast can be used in situations where you might be endangering the user's data. Say in a database engine, when you detect a corruption of your internal data structures, the only sane course of action is to halt the process as quickly as possible, to avoid writing garbage to the database and risk corrupting it and lose the user's data. This is one possible scenario where failfast is useful.
Another use is to catch programmer errors. Say you are writing a library and some function accepts a pointer that cannot be null in any circumstance, that is, if it's null, you are clearly in presence of a programmer error. You can return an error like E_POINTER or throw some InvalidArgument exception and hope someone notices, but you'll get their attention better by failing fast :-)
Note that I'm not restricting the example to pointers, you can generalize to any parameter or condition that should never happen. Failing fast ultimately results in better quality apps, as many bugs no longer go unnoticed.
Finally, failing fast helps with capturing the state of the process as faithfully as possible (as a memory dump gets created), in particular when failing fast immediately upon detecting an unrecoverable error or a really unexpected condition.
If the process was allowed to continue, say the 'finally' clauses would run or the stack would be unwound, and things would get destroyed or disposed-of, before a memory dump is taken, then the state of the process might be altered in such as way that makes it much more difficult to diagnose the root cause of the problem.
It kills the application and even skips try/finally blocks.
From .NET Framework Design Guidelines on Exception Throwing:
✓ CONSIDER terminating the process by calling System.Environment.FailFast (.NET Framework 2.0 feature) instead of throwing an exception if your code encounters a situation where it is unsafe for further execution.
Joe Duffy discusses failing fast and the discipline to make it useful, here.
http://joeduffyblog.com/2014/10/13/if-youre-going-to-fail-do-it-fast/
Essentially, he's saying that for programming bugs - i.e. unexpected errors that are the fault of the programmer and not the programme user or other inputs or situations that can be reasonable expected to be bad - then deciding to always fail fast for unexpected errors has been seen to improve code quality.
I think since its an optional team decision and discipline, use of this API in C# is rare since in reality we're all mostly writing LoB apps for 12 people in HR or an online shop at best.
So for us, we'd maybe use this when we want deny the consumer of our API the opportunity of making any further moves.
An unhandled exception that is thrown (or rethrown) within a Task won't take effect until the Task is garbage-collected, at some perhaps-random time later.
This method lets you crash the process now -- see this answer.

Categories