What is the right approach when no handler is found in the call stack in C# program - c#

I ask this question because soon I'll have interview heavily focused on error handling but also this is something I haven't figure out even though I have almost 7 months as a junior C# developer.
As the title says I want to know what is the right way to deal with exceptions form which there is no appropriate error handler. Some time ago I've heard a colleague of mine talking about generic exception handler (whatever that may mean) which is responsible to deal with suck case scenarios. However I did I little googling I haven't been able to find some information about such a thing.
So my question is - how to deal with those kind of exceptions and my subquestion is - is there really something called generic exception handler?

is there really something called generic exception handler?
Yes - that's what they call the handler that logs the exception and stores as much info as possible before quitting the program. One way to set up a handler like that is adding a handler to the UnhandledException event of your AppDomain object.
It is neither "generic" nor a "handler" in the .NET sense, because no generic types are involved, and because the actions the handler could take are rather limited. Unlike a real handler which could block or re-throw the exceptions that it handles, the last-chance "handler" could see what's been thrown, but cannot cause the execution to continue.

Uncaught exceptions will result in applicaiton crash. You can subscribe to AppDomain.UnhandeledException event to get notified about such situation, write some message in log, e.t.c.
However, you cannot prevent applicaiton from crashing in that handler, because there will be no point from which the execution could continue.

The way you deal with unplanned exceptions is to catch them, log them to some place where a developer will review them for bugs, and then abort the action that way just being tried. This might mean that you show the user an error message, that you shut down the application or that you let a framework like ASP.NET handle the exception (it will "handle" it by showing a generic error page).
Unplanned exceptions can always occur due to bugs. You need a strategy to deal with that (as described above).
A "generic" exception handler would be a catch (Exception ex). In other words, a catch-all. That is not an official term, but that's what the person meant.

Related

General way to handle exceptions

I'm trying to design the exception handling mechanism in my web app, and got into some difficulties in the design.
As much as I know - there are three ways to catch exceptions in ASP.NET app -
In the code itself (try, catch, finally)
In the Page_Error event of the page
In the Application_Error event of the global.asax page
Since I have many events and functions in my .aspx pages, I wanted one single place that will catch and collect exceptions.
In other words- I really don't feel like spreaindg try-catch statments all over the code, so I thought using the Page_Error event (which I read might be good practice at some cases).
However, a problem arises because all I want the exception handler to do is to show a nice alert on the page itself informing about general problem that took place, but as you probably know - when you get to Page_Error the page is already dead and failed to render.
So, what other generic way is there to catch exceptions, in a manner that when I will write functions in the future I won't need to think about exceptions or try-catch, but instead know that there is a mechanism somewhere out there that will catch everything and handle it?
Use Elmah - http://code.google.com/p/elmah/
This will catch and log any unhandled errors, without your writing a line of code :)
Since an exception occurred it means the page could not render (for whatever reason). This will cause an exception to propogate up the call stack until it is handled somewhere. The last place you can handle an exception in ASP.NET is within global.asax and since there was a problem you can create whatever output you want to be written to the client:
protected void Application_Error(Object sender, EventArgs e)
{
Response.Write("Really sorry this happened")
}
This method will ensure all (unhandled) exceptions will be caught and treated in this way, so you'll also likely want to implement some kind of logging system here too.
Of course you can also specify a custom error page in the web.config.
I use Application_Error to log the error and then do a Server.Transfer to a custom error page. By doing it this way I can grab the exception on that page and decide how to display it. I worry though that if you are wanting to show the exception in an alert that you may be using exceptions for the wrong purpose. You aren't throwing exceptions for validation errors or something else that can be anticipated, are you?
I believe that not try/catching exceptions at all could restrict you from some benefits/techniques like Repeating a function in C# until it no longer throws an exception. Anyway you can allow show custom error page on web.config if it fits.
I would personally use Application_Error in order to log that exceptions, but in this sense, better would be giving #MoXplod advice a try.
Btw, I might not be totally correct but writing the stacktrace to a page when an error occurs could consist of a security issue.
The only real way to properly handle exceptions is to do so as close as possible to the offending code. This way you have much better control over how it should be best handled. In other words, having those try-catch statements "all over the code".
Take, for example this bit of code:
Int32 value = 0; // let's say this was passed in.
double newValue = 5 / value;
Is it better to alert the user that a problem occurred or is it better to have a fall back plan, for example, just assigning 0 to newValue? Your answer may change depending on the situation; however, if you are dealing with this in a generic way you artificially limit yourself.
In my case I ended up using Post Sharp, an AOP framework. I used it to enter some policy when exception occured.
Another option is Enterprise Library's policy injection, which allows code insertion in particular cases, such as - methods or classes surrounded by an attribute, and an Exception Handling Module attached to it.
This way or another, the solution for catching exception in an "abstract" (so to speak) level without filling the code with try-catch will probaby contain this amount of AOP.
goodluck

Wouldn’t handling an exception be a better idea

1)
1 - Only handle exceptions that you
can actually do something about, and
2 - You can't do anything about the vast majority of exceptions
a) I assume that “By not handling an exception” the text is suggesting that we should let the exception bubble up the stack, where runtime will abort our application?!
b) But why is letting the runtime abort the exception preferred over catching an exception, logging it and then informing the user of failure? Only difference between the two is that in the latter case application isn’t aborted
For example, if database goes down, why should the whole program crash ( due to not handling an exception ), if we can instead catch the exception, log it and notify user of failure and that way we can keep the program up and running
2) If you know that exception potentially raised by some block of code can’t be handled, should you include this code inside a try-finally block or is it better to leave it outside any try-finally blocks?
Thank you
No, the guideline is not to catch an exception you cannot do anything about except at the top-level of your application or thread.
You should try to avoid letting your application crash - log the information somewhere, give a message to your user explaining what happened, and tell them how to report the error to you. Perhaps also try to save their unsaved data in a recovery file so that the next time the application starts it can offer the option to attempt to recover their lost work.
Try looking at it this way... The database goes down. How do you know? Because you get an timeout/an exception/something. But your application probably isnt getting the exception. ADO.NET/Linq to SQL/Entity Framework/Whatever data provider you are using is actually getting the exception and throwing it to your application. To me, this is what that advice is advising: as a component designer, prefer to throw exceptions you can't do anything about.
For the database down example, is there anything the ADO.NET data provider can do? Can it bring a server back up? Repair network connections? Reset permissions? No. So it doesn't handle the exception, it throws it.
The guideline you cite is for component development, not the outer edge of a run-time boundary (a thread or application). At that level, it would be correct to make a decision on how to handle exception that have bubbled that far.
I think the person you are quoting suggests that you should let the exception bubble up the stack until something higher up can make sense of it or until it reaches the top of the call stack where you do have code that would log it, or display a error message to the user then exit your program if it is fatal, or carry on if it is not.
Sometimes it may be better to not continue executing the program - if you get a OutOfMemoryException for example or some other situation where the programs actions are undefined - a potential disaster.
I think the key to
Only handle exceptions that you can actually do something about
is that you should only handle the exception if you can carry on from that point in your application.
To take a trivial example.
If you're looking for a file on the user's system and it's not there when it should be you should raise the "file not found" exception. Now if you can recover from this (say by simply recreating the file) then do so and carry on. However, if the file can't be recreated then you shouldn't let your program carry on.
However, this doesn't mean you can't have a top level catch all exception handler in your main program to display a friendly message to the user, perhaps to log the exception or even mail it to you the developer.
That statement holds true. But it is a reference to catching exception in the deeper layers of application. Basically most of the code we write does not need exception handling. It is only the client part of the application is responsible for catching the error and presenting it to the user - as well as logging.
For example, the same business code/database code can be used in a web application and windows/wpf application and logging/handling could be different and deeper layers do not know about how this will be handled so they need to leave the responsibility to the UI tier.
The point is that you don't want to have try/catch blocks nested everywhere in your code as this tends to hide issues with your code. It is better to only implement exception handling where you understand the error and the desired outcome, else don't handle it and let it bubble up.
As for as the errors bubbling up, you should have a global exception handler for these uncaught application errors. This is only implemented in one spot in your app and will allow you to log or present the error to the user. Again this is only implemented in one spot in your app, and is implemented by hooking the application.error event.
Event to hook in .net win forms application:
AppDomain.CurrentDomain.UnhandledException
Event to hook in .net asp.net application:
HttpApplication.Error
Enjoy!
Without knowledge about the context of both statements, stated that both statements apply to methods and classes then they make sense:
A piece of code which calls a method can only handle exceptions for which it has enough information about the context. In most cases a piece of code won't have enough information, to handle all exceptions.
Example: A piece of code, which calls a method SaveData() can handle a DatabaseStorageException when it knows, that it saves data to a database. On the other hand, if the piece of code is programmed in a storage agnostic manner, than catching such a specific exception is not a very good idea. In this case it is better to let the exception pop up the callstack and let some other code handle the exception, which has enough context information to handle it.

Would you ever NOT catch an exception, or throw an exception that won't be caught?

I've dealt with instances where I would throw/rethrow an exception knowing that the code surrounding it would catch the specific exception. But is there any time you would want to throw an exception, knowing that it wouldn't be caught?
Or at least, NOT catch an exception?
Exceptions immediately halt the application unless their handled right? So I guess I'm asking if you would ever want to purposely let your application die?
If your application is primarily going to be used by other clients and is not standalone, it generally makes sense to throw exceptions if a condition arises that you don't know how to (or don't want to) handle, and there's no sensible way for you to recover from it. Clients should be able to decide how they want to handle any exceptions that you might throw.
On the other hand, if your application is the endpoint, throwing an exception essentially becomes a notification mechanism to alert people that something has gone terribly wrong. In such cases, you need to consider a few things:
How important is the continued running of the application? Is this error really unrecoverable? Throwing an exception and terminating your program is not something you want to be doing on the space shuttle.
Are you using exceptions as a proxy for real logging? There's almost never a reason to do this; consider a real logging mechanism instead. Catch the exception and have the logger work out what happened.
What are you trying to convey by throwing the exception yourself? Ask yourself what the value in throwing a new exception is, and consider carefully whether there isn't a better way to do what you want.
Not catching an exception may leave resources in a bad state. If you don't gracefully exit, things are generally not cleaned up for you. Make sure you understand what you're doing if you need to do this -- and if you're not going to catch it, at least consider a try-finally block so you can do some tidying up.
There's a very good rule that I came across a while ago:
Throw an exception when a method can't do what its name says it does.
The idea is that an exception indicates that something has gone wrong. When you are implementing a method, it is not your responsibility to be aware of whether it will be used correctly or not. Whether the code using your method catches the exception or not is not your responsibility, but the responsibility of the person using your method.
Another rule to follow is:
Don't catch an exception unless you know what you want to do with it.
Obviously, you should include cleanup code in a try...finally block, but you should never just catch an exception just for the sake of catching it. And you should never swallow exceptions silently. While there are occasions when you may want to catch all exceptions (e.g. by doing catch (Exception ex) in C#), these are fairly uncommon and generally have a very specific technical reason. For example, when you are using threads in .NET 2.0 or later, if an exception escapes from your thread, it will cause the entire application domain to unload. In these cases, however, at the very minimum you should log the exception details as an error and provide an explanation in the comments.
Sure. For example, if you're trying to load some bytes into a string in Java:
try {
String myString = new String(byteArray, "UTF-8");
} catch (UnsupportedEncodingException e) {
// Platform doesn't support UTF-8? What is this, 1991?
throw new RuntimeExceptione(e);
}
In this case, there is no graceful degradation, the platform simply can't support the operation desired. You can check for this condition at initialization all you want, but the constructor for String still throws this exception, and you have to deal with it. Either that, or use Charset.forName() :)
Generally, and certainly in early iterations of your application, don't catch the exception. More often than not, the recovery from an exception will require a business rule of some sort, and, more often than not, those business rules are not defined for you. If you "handle" the exception instead of letting the application die then you will most likely be inventing business rules for your customer. Not good.
The general pattern of catching every exception just for the sake of catching it has caused me more headaches than I can count. It usually happens that someone puts some sort of generic exception handling code throughout the application, which inevitably ends up hiding a bug or creating some behavior that is unwanted. (incidentally, catching and then not rethrowing is even worse.)
So, I'd suggest that you ask instead: "When should I catch an exception?"
Here's the thing ... it is about "layers", or "encapsulation", or "low coupling". At some place in your codebase, you're writing a method to do something. Say it's a public method. Therefore, it should not assume much or anything about the caller ... rather, it should merely do the job it is supposed to do, regardless of who is calling it and what context the caller is in.
And if, for some reason, it cannot complete its job, then it needs to tell the caller "Sorry, I couldn't do that, and here's why". Exceptions are an excellent mechanism to let it tell the caller that (not the only mechanism, but the best mechanism I've ever seen for most cases).
So, when you throw the exception, you have no idea whether it will be caught or not ... because you're exposing a public method and you have no idea who might choose to call it and why.
The catching of the exception is the job of the "context". For example, say you're writing a library with public methods that might throw exceptions. Then, say you're using that library from a Windows Forms app. The Windows Forms app might catch exceptions and show a message box to the user.
But later, you might use the same library from a Windows Service. The Service would be more likely to catch the exception, log it, return an error to the original caller, but keep running so it can process further requests.
So the exception is like a contractual agreement between the caller and the provider. The provider says, "I'll either do the job or tell you why I can't. What you do from there is your own business." And the caller says, "OK, if you can't do the job, just tell me why, and I'll decide what to do in that case."
But is there any time you would want to throw an exception, knowing that it wouldn't be caught?
I would say that if you're manually throwing an exception, most of the time you don't know if it will be caught. If you knew it would be caught you could just handle it yourself rather than throwing the exception in the first place.
To be fair, I suppose that depends in part on the kind of programming you're doing, and sometimes the same programmer ends up building both the library and the code that consumes said library.
Would you ever NOT catch an exception?
If you didn't expect/weren't aware an exception could be thrown. But putting that aside and assuming you are aware of the exception, sometimes you know about it at one tier but know the next tier up is the more appropriate place to handle it.
It depends on the type of application. Web applications can continue running even after exceptions have bubbled up to the execution context.
It is common practice to 'throw/rethrow' an exception if you catch the exception at a level where it can't be dealt with. But, you would almost always add context to the issue, at the very least add some logging at the higher level to say that it was caught and rethrown.
for example
A calls B calls C (throws exception)
B catches/rethrows
A catches.
In this case, you would want B to add some logging so that you can differentiate between B generating and throwing an error, and C generating and throwing an error. That would allow you a greater ability to debug and fix problems later.
In general you will almost NEVER want an exception to kill your program. The best practice is to catch the except and exit gracefully. This allows you to save any currently open information and release resources that are being used so they don't become corrupted. If you intend to exit, you can create your own 'core-dump' information report that includes the things you were doing when you caught the fatal exception.
If you let the exception kill your process you are eliminating your chance to get custom tailored crash information, and you are also skipping the part where you provide the user with a friendly error message and then exit.
So, I would recommend ALWAYS catching exceptions, and never voluntarily letting them run amok in your program.
EDIT
If you are writing a library, you have to choose ahead of time whether your function will throw an exception, or be exception safe. In those cases, sometimes you will throw an exception and have no idea if the calling party will catch it. But in that case, catching it is not your responsibility, as long as the api declares that the function could throw exceptions.
(I'm looking for a word that means 'could possibly throw exception'... anyone know what it is? It's going to bug me all day.)
Firstly, there absolutely are situations where it is better to not catch an exception.
Sometimes, an exception can sometimes tell you that your program is in an unknown state. There are a number of exceptions where this is pretty much intrinsically true given the exception type. A NullReferenceException essentially tells you "there is a bug". And by catching such an exception, you may hide the bug, which sounds good in the short term, but in the long term you'd be happier to fix it. The product may not crash, but it certainly won't have the expected behaviour.
But this is also true for exception types we invent for ourselves. Sometimes, the fact that exception A has been thrown should be "impossible" - and yet it has happened, so there's a bug.
Also, something very important happens when you catch an exception: the finally blocks for the whole call stack inside the try block (and anything it calls) will be executed. What do those finally blocks do? Well, anything. And if the program is in an unknown state, I really do mean anything. They could erase valuable customer data from the disk. They could throw more exceptions. They could corrupt data in memory, making the bug impossible to diagnose.
So when an exception indicates an unknown state, you don't want to run any more code, so whatever you do, don't catch the exception. Let it fly past, and your program will terminate harmlessly, and Windows Error Reporting will be able to capture the state of the program as it was when the problem was originally detected. If you catch the exception, you will cause more code to execute, which will screw up the state of the program further.
Secondly, should you throw an exception knowing it won't be caught? I think that question misunderstands the nature of reusable methods. The whole idea of a method is that it has a "contract" that it follows: it accepts certain parameters and returns a certain value, plus also it throws certain exceptions under certain conditions. That's the contract - it's up to the caller what they do with it. For some callers, exception A might indicate a recoverable condition. For other callers, it might indicate a bug. And from what I said above, it should be clear that if an exception indicates a bug, it must not be caught.
And if you're wondering what this means for the Microsoft Enterprise Library's Exception Handling Block: yes, it's pretty broken. They tell you to catch (Exception x) and then decide whether to rethrow based on your policy; too late - the finally blocks have already executed by that point. Don't do that.
You probably wouldn't want an uncaught exception anywhere where the end-users can see it, but it is often acceptable to let clients of your API (other programmers) decide how to handle exceptions.
For example, suppose you are designing a Java class library. You expose a public method that takes in a String. In your application, a null input value would cause an error. Instead of handling the error yourself, it would be acceptable to check for a null value, then throw an IllegalArgumentException.
You must, of course, document that your method throws this exception in this circumstance. This behavior becomes part of your method's contract.
It depends on what you mean by 'being caught'. Something, somewhere eventually catches the exception whether it be the underlying OS or something else.
We have a workflow system that executes job plans comprised of individual jobs. Each job runs a unit of code. For some of the exceptions, we don't want to handle them in the code but throw it up the stack so that the external workflow system catches it (which happens completely outside of the thrower's process).
If you're writing the entire application, then your reasons are your own. I can think of a few situations where you might want to throw the exception and let the app die, most of them are not very good reasons though.
The best reason is usually when debugging. I frequently disable exceptions while debugging to allow me to know better where something is failing. You can also just turn on thrown exception breaks in the debugger if you're running it on a machine with the debugger.
Another possible reason is when continuing after an exception is thrown doesn't make sense or would result in possible irrecoverable data corruption or worse (think Robots with laser beams, but then you should be damn sure your applicaiton deals with these situations IMO, crashing the program is just the lazy way).
If you're writing API code, or Framework code that you won't use yourself, then you have no idea if someone will catch your exceptions.
Yup, it's my ONLY opportunity to slap the developer consuming the service/object to tell them "Ur dO1n it WrOnG!!!!".
That and getting rid of possibilities that you don't want to permit or are seemingly "impossible". Apps that catch all exceptions and continue are just a walled garden surrounded by chaos.
If I need a moderately large system that is somehow processing data in what I believe to be a consistent manner.
And
Somewhere along the line, I detect that the application's state has become inconsistent.
And
The system doesn't (yet) know how to fix the inconsistency and recover gracefully
Then, yes, I would throw an exception with as much detail as possible and cause the application to die as quickly as possible, to avoid doing any further harm to the data. If it can be recovered, it'd be important not to exacerbate the problem by trying feebly to cover up the mess.
Later along the line, once the chain of events that led to the inconsistency is better understood, I higher facility can catch that exception, repair the state, and continue with minimal interruption.
A library will often throw exceptions based on defensive programming checks, should a condition arise that shouldn't have been allowed to arise by the application code. Applications code will often be written such that most of those invalid conditions will never arise, and therefore the exceptions will never be thrown, so there's no point catching them.
Depending on language (I'm mostly thinking in terms of C++ rather than C#, and not that clear what the differences are) the effect of an uncaught exception actually being thrown is probably the same as what used to be done in the days before exceptions were invented. A common policy for defensive programming in C libraries, for example, was to terminate the program immediately with an error message.
The difference is that if the exception throw does turn out to be possible (hopefully this will be discovered through unit testing), it is often relatively easy to add an exception handler that can recover from the problem in a more constructive way. You don't have to rewrite the library, or add complex checks in application code to ensure the condition cannot arise before the exception-throwing call is made.
I have quite a few exception throws that are never caught. They are all for defensive purposes, and while being uncaught is bad for an exception that does happen, this only ever happens during development and testing, for error conditions I failed to consider in the application code so far. And when it happens, it is unusual for the fix to be awkward - no need for a large-scale refactoring, no need for the applications code to be massively complicated with error condition checks, just a catch clause with a relatively simple recovery or "I'm sorry, Dave, I'm afraid I can't do that." without failing out the whole app.

How to catch ALL exceptions/crashes in a .NET app [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
.NET - What’s the best way to implement a “catch all exceptions handler”
I have a .NET console app app that is crashing and displaying a message to the user.
All of my code is in a try{<code>} catch(Exception e){<stuff>} block, but still errors are occasionally displayed.
In a Win32 app, you can capture all possible exceptions/crashes by installing various exception handlers:
/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler
What is the equivalent in the .NET world so I can handle/log/quiet all possible error cases?
You can add an event handler to AppDomain.UnhandledException event, and it'll be called when a exception is thrown and not caught.
Contrary to what some others have posted, there's nothing wrong catching all exceptions. The important thing is to handle them all appropriately. If you have a stack overflow or out of memory condition, the app should shut down for them. Also, keep in mind that OOM conditions can prevent your exception handler from running correctly. For example, if your exception handler displays a dialog with the exception message, if you're out of memory, there may not be enough left for the dialog display. Best to log it and shut down immediately.
As others mentioned, there are the UnhandledException and ThreadException events that you can handle to collection exceptions that might otherwise get missed. Then simply throw an exception handler around your main loop (assuming a winforms app).
Also, you should be aware that OutOfMemoryExceptions aren't always thrown for out of memory conditions. An OOM condition can trigger all sorts of exceptions, in your code, or in the framework, that don't necessarily have anything to do with the fact that the real underlying condition is out of memory. I've frequently seen InvalidOperationException or ArgumentException when the underlying cause is actually out of memory.
This article in codeproject by our host Jeff Atwood is what you need.
Includes the code to catch unhandled exceptions and best pratices for showing information about the crash to the user.
The Global.asax class is your last line of defense.
Look at:
protected void Application_Error(Object sender, EventArgs e)
method
Be aware that some exception are dangerous to catch - or mostly uncatchable,
OutOfMemoryException: anything you do in the catch handler might allocate memory (in the managed or unmanaged side of the CLR) and thus trigger another OOM
StackOverflowException: depending whether the CLR detected it sufficiently early, you might get notified. Worst case scenario, it simply kills the process.
You can use the AppDomain.CurrentDomain.UnhandledException to get an event.
Although catching all exceptions without the plan to properly handle them is surely a bad practice, I think that an application should fail in some graceful way. A crash should not scare the user to death, and at least it should display a description of the error, some information to report to the tech support stuff, and ideally a button to close the application and restart it. In an ideal world, the application should be able to dump on disk the user data, and then try to recover it (but I see that this is asking too much).
Anyway, I usually use:
AppDomain.CurrentDomain.UnhandledException
You may also go with Application.ThreadException Event.
Once I was developing a .NET app running inside a COM based application; this event was the very useful, as AppDomain.CurrentDomain.UnhandledException didn't work in this case.
I think you should rather not even catch all Exception but better let them be shown to the user. The reason for this is that you should only catch Exceptions which you can actually handle. If you run into some Exception which causes the program to stop but still catch it, this might cause much more severe problems.
Also read FAQ: Why does FxCop warn against catch(Exception)?.
Be aware that catching these unhandled exceptions can change the security requirements of your application. Your application may stop running correctly under certain contexts (when run from a network share, etc.). Be sure to test thoroughly.
it doesn't hurt to use both
AppDomain.CurrentDomain.UnhandledException
Application.ThreadException
but keep in mind that exceptions on secondary threads are not caught by these handlers; use SafeThread for secondary threads if needed

Exception handling using an HttpModule

We're reviewing one of the company's system's exception handling and found a couple of interesting things.
Most of the code blocks (if not all of them) are inside a try/catch block, and inside the catch block a new BaseApplicationException is being thrown - which seems to be coming from the Enterprise Libraries.
I'm in a bit of a trouble here as I don't see the benefits off doing this. (throwing another exception anytime one occurs)
One of the developers who's been using the system for a while said it's because that class's in charge of publishing the exception (sending emails and stuff like that) but he wasn't too sure about it.
After spending some time going through the code I'm quite confident to say, that's all it does is collecting information about the environment and than publishing it.
My question is:
- Is it reasonable to wrap all the code inside try { } catch { } blocks and than throw a new exception? And if it is, why? What's the benefit?
My personal opinion is that it would be much easier to use an HttpModule, sign up for the Error event of the Application event, and do what's necessary inside the module. If we'd go down this road, would we miss something? Any drawbacks?
Your opinion's much appreciated.
Never1 catch (Exception ex). Period2. There is no way you can handle all the different kinds of errors that you may catch.
Never3 catch an Exception-derived type if you can't handle it or provide additional information (to be used by subsequent exception handlers). Displaying an error message is not the same as handling the error.
A couple of reasons for this, from the top of my head:
Catching and rethrowing is expensive
You'll end up losing the stack trace
You'll have a low signal-to-noice ratio in your code
If you know how to handle a specific exception (and reset the application to pre-error state), catch it. (That's why it's called exception handling.)
To handle exceptions that are not caught, listen for the appropriate events. When doing WinForms, you'll need to listen for System.AppDomain.CurrentDomain.UnhandledException, and - if your doing Threading - System.Windows.Forms.Application.ThreadException. For web apps, there are similar mechanisms (System.Web.HttpApplication.Error).
As for wrapping framework exceptions in your application (non-)specific exceptions (i.e. throw new MyBaseException(ex);): Utterly pointless, and a bad smell.4
Edit
1 Never is a very harsh word, especially when it comes to engineering, as #Chris pointed out in the comments. I'll admit to being high on principles when I first wrote this answer.
2,3 See 1.
4 If you don't bring anything new to the table, I still stand by this. If you have caught Exception ex as part of a method that you know could fail in any number of ways, I believe that the current method should reflect that in it's signature. And as you know, exceptions is not part of the method signature.
If I am reading the question correctly, I would say that implementing a try / catch which intercept exceptions (you don't mention - is it catching all exceptions, or just a specific one?) and throws a different exception is generally a bad thing.
Disadvantages:
At the very least you will lose stack trace information - the stack you will see will only extend to the method in which the new exception is thrown - you potentially lose some good debug info here.
If you are catching Exception, you are running the risk of masking critical exceptions, like OutOfMemory or StackOverflow with a less critical exception, and thus leaving the process running, where perhaps it should have been torn down.
Possible Advantages:
In some very specific cases you could take an exception which doesn't have much debug value (like some exceptions coming back from a database) and wrap with an exception which adds more context, e.g id of the object you were dealing with.
However, in almost all cases this is a bad smell and should be used with caution.
Generally you should only catch an exception when there is something realistic that you can do in that location- ie recovering, rolling back, going to plan B etc. If there is nothing you can do about it, just allow it to pass up the chain. You should only catch and throw a new exception if there is specific and useful data available in that location which can augment the original exception and hence aid debugging.
I'm from the school of thought where try/ catch blocks should be used and exceptions not rethrown. If you have executing code which is likely to error then it should be handled, logged and something returned. Rethrowing the exception only serves the purpose to re-log later in the application life cycle.
Here's an interesting post on how to use a HttpModule to handle exceptions: http://blogs.msdn.com/rahulso/archive/2008/07/13/how-to-use-httpmodules-to-troubleshoot-your-asp-net-application.aspx and http://blogs.msdn.com/rahulso/archive/2008/07/18/asp-net-how-to-write-error-messages-into-a-text-file-using-a-simple-httpmodule.aspx
Check out ELMAH. It does what you're talking about. Very well.
When I create libraries I try to always provide a reduced number of exceptions for callers to handle. For example, think of a Repository component that connects to a sql database. There are TONS of exceptions, from sql client exceptions to invalid cast exceptions, that can theoretically be thrown. Many of these are clearly documented and can be accounted for at compile time. So, I catch as many of them as I can, place them in a single exception type, say a RepositoryException, and let that exception roll up the call stack.
The original exception is retained, so the original exception can be diagnosed. But my callers only need to worry about handling a single exception type rather than litter their code with tons of different catch blocks.
There are, of course, some issues with this. Most notably, if the caller can handle some of these exceptions, they have to root around in the RepositoryException and then switch on the type of the inner exception to handle it. Its less clean than having a single catch block for a single exception type. I don't think thats much of an issue, however.
Sounds like the exception that is thrown should not have been implemented as an exception.
Anyway, I would say that since this BaseApplicationException is a general all-purpose exception, it would be good to throw exceptions that are more context-specific. So when you are trying to retrieve an entity from a database, you might want an EntityNotFoundException. This way when you are debugging you do not have to search through inner exceptions and stack traces to find the real issue. If this BAseApplicationException is collecting information on the exception (like keeping track of the inner exception) then this should not be a problem.
I would use the HttpModule only when I could not get any closer to where the exceptions are actually happening in code. You do not really want an HttModule OnError event that is a giant switch statement depending on BaseApplicationexception's error information.
To conclude, it is worth it to throw different exceptions when you can give more specific exceptions that tell you the root of the problem right off the bat.
From my experience, catch the exception, add the error to the Server (?) object. This will allow .NET to do what ever it needs to do, then display your exception.

Categories

Resources