i have to implement a Info Terminal. I choose dot.net and the terminal is only a touchpad.
So this System running 7 days 24 hours.
So i call a Webservice, display Data, show Website stuff. Many things can going wrong.
Have you some recommendations for this scenario?
Every function in an try catch? AppDomain.CurrentDomain.UnhandledException event?
Thanks Andreas
Basically, you should handle any error as soon as it is possible - so if you're calling webservice wrap all the calls in a try/catch block and handle the error there - you can, for example, log the exact error, aggregate many webservice-related exception in more generic, DataSourceFaultException (name is only for example), which will be then received by UI and UI will be able to easily determine, that it can't display requested info because communication failed, and choose to retry, notify user or do anything else.
However - with long running application there are many more errors you'll have to deal with. Many of them are not easy to predict, as they're not necessarily related to any specific call - you can run out of memory, a recursion might cause stack overflow, a system timer can reach it's max value and start from the beginning etc.
You shouldn't handle those errors in every method, as it will only hurt code readibility and will be error prone. Those errors are best handled by UnhandledException event. However, you must remember, that when the exception reaches UnhandledException event, you cannot assume anything about state of your application - the error might have corrupted some (or even all) of internal state. So when such condition occurs, it's best to try to create an error log and gracefuly restart the application (not necessarily whole application - maybe it will be possible to reinitialize application's state - if so, that's a valid option too. However, you must be aware that you won't be able to recover from some errors and handle such situation anyway).
It depends.
If you can handle appropriately an exception within a function - handle it. If not - create a global exception handler to inform user or log it.
Related
Our application is modulraized (Group of modules doing specific things). The modules have event handlers. These events could be fired from other modules or the application menu.
Situation:
Module A(which have UI) recieves an event "deleteitem". The event arguments should contain the item name to be deleted. But in this case it is null. Somewhere, somebody messed with something.
Question(s):
Should the Module throw? Rememeber, the module would be throwing inside an event handler and could crash the app as the module writer have no idea if the exception is handled.
The above scenario is a snaphot of a bigger question regarding throwing of excpetions from Modules which could result in application crashing. The argument against it is the application can continue working without the specific modules. Well then, who should ensure that - the module or the application?
If the item name is something that is expected to always be there and it being null is an exceptional circumstance, which should never happen, you should throw as now your application is in an unknown state that should never happen
If this is something that the caller can recover from, they will write their own exception handling routines to handle it.
Is it an essential event? Can you ignore it? I would treat that as an empty event and ignore it. I guess not being able to delete something is not mission critical. Good idea is to log this information as a warning or error perhaps, so you know it happened.
My rule would be that if something can be re-issued it is not essential but if it can't - it is important. But that can change depending on particular application context.
Bad things happen and if you can you should try to recover from them. My priority would be to ensure application (module) does not crash even if is fed wrong data but definitely make sure you know bad things happen (logging). Exception is the last resort if you're helpless and can't do anything else.
What I described here would best apply to separated modules like WCF services for example. If it is all in one app (modules are classes), probably best would be to return an exception but make sure caller can handle it. So modules separation is important here - the more separation the more error resiliency should there be. WCF services or Windows services should not crash.
Do throw. React to any such exceptions by fixing the module that is throwing the malformed event, as soon as they are discovered.
The answer partly depends on how you build and version the product (whether the module that fires the event is maintained and built together with all the listeners).
Because you are describing a pretty extreme behavior, indicating a product defect, it is good to find it as early as possible. If you do not have a better method of alerting anyone who is using or testing the defective software, do throw.
On the other hand, do not throw in less extreme circumstances, such as when the event might be well formed, or when your own module might be responsible for it.
Product defects are cheapest to fix if found relatively early; but excessive throwing may cause defect propagation to unrelated modules (that will receive some but not all related events) and thus delay pinning the defect down.
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.
I have added a global error handler at the AppDomain level to my C# application, by hooking into the UnhandledExceptionHandler event.
My problem is, that even though i am handling this exception, i still get the popup saying "App has stopped working".
Is this normal behaviour? Can it be turned off? or maybe it is good practice to actually have this message displayed?
Is this normal behaviour?
Yes. Think about it, where should your code be resumed? In what state?
Can it be turned off?
Only by handling exceptions a the appropriate point in your program, ie in the toplevel code. The UnhandledExceptionHandler is not a replacement but a diagnosis-tool for incomplete handling.
or maybe it is good practice to actually have this message displayed?
Yes. You should log exceptions that arrive there but you've already lost control.
I don't think is possible to recover the existing instance of an app when you get at that point. MSDN has no information about it and is suggested " If sufficient information about the state of the application is available, other actions may be undertaken — such as saving program data for later recovery." (link)
It kind of makes sense to not be able to recover. If you catch an exception in the Unhandled ExceptionHandler it means that your application was not able to deal with it so is your last chance to log what happened (for later investigations) or save the user's data. It sounds like an architecture problem if the "unhandled" exception handler must "handle" exceptions and recover the app.
Why not recover by creating a new instance of the app? (or by using the Restart and Recovery feature)
Which is the best place to handle the exceptions ? BLL, DAL or PL ?
Should I allow the methods in the DAL and BLL to throw the exceptions up the chain and let the PL handle them? or should I handle them at the BLL ?
e.g
If I have a method in my DAL that issues "ExecuteNonQuery" and updates some records, and due to one or more reason, 0 rows are affected. Now, how should I let my PL know that whether an exception happened or there really was no rows matched to the condition. Should I use "try catch" in my PL code and let it know through an exception, or should I handle the exception at DAL and return some special code like (-1) to let the PL differentiate between the (exception) and (no rows matched condition i.e. zero rows affected) ?
It makes no sense to let an exception that is thrown in the DAL bubble up to the PL - how is the user supposed to react if the database connection could not be established?
Catch and handle exceptions early, if you can handle them. Do not just swallow them without outputting a hint or a log message - this will lead to severe difficulties and bugs that are hard to track.
The short answer is it depends!
You should only ever handle an exception if you can do something useful with it. The 'something useful' again depends on what you are doing. You may want to log the details of the exception although this isn't really handling it and you should really re-throw the exception after logging in most circumstances. You may want to wrap the exception in some other (possibly custom) exception in order to add more information to the exception. As #mbeckish touches on, you may want to try to recover from the exception by retrying the operation for example - you should be careful not to retry forever however. Finally (excuse the pun) you may want to use a finally block to clean up any resources such as an open DB connection. What you choose to do with the exception will influence where you handle it. It is likely that there isn't a great deal of useful things that can be done with many exceptions other than to report to the user that an error has occurred in which case it would be more than acceptable to handle the exception in the UI layer and report the problem to the user (you should probably log the exception as well, further down your layers).
When throwing exceptions yourself, you should only ever throw exceptions in 'exceptional'circumstances as there is a big overhead in throwing exceptions. In your example you suggest you may be thinking of throwing an exception if no records are updated by your operation. Is this really exceptional? A better thing to do in this situation would be to return the number of records updated - this may still be an error condition that needs to be reported to the user, but isn't exceptional like the command failing because the connecction to the DB has gone down.
This is a reasonable article on exception handling best practices.
This is a huge topic with lots of unneeded controversy (people with loud voices giving bad info!) If you're willing to deal with that, follow s1mm0t's advice, it is mostly agreeable.
However if you want a one-word answer, put them in the PL. Serious. If you can get away with it put your error handling in a global exception handler (all errors should log and give a code to look up the log in production for security reasons (esp if web), but give the full details back during development for speed reasons).
Edit: (clarification) you have to deal with some errors everywhere - but this is not an 'every function' norm. Most of the time let them bubble up to the PL and handle .NET's global error with your own code: log the full call stack from there via a common routine that is accessible from all 3 layers via event handlers (see EDIT at bottom of message). This means you will not have try/catch sprinkled thru all your code; just sections you expect and error and can handle it right there, or, non-critical sections, with which you log the error and inform the user of unavailable functionality (this is even more rare and for super-reliable/critical programs)
Aside from that, when working with limited-resource items, I often use the 'using' keyword or try/finally/end try without the catch. for multithreading lock/mutex/re-entry prevention flags/etc. you also need try/finally in ALL cases so your program still works (especially stateful apps).
If you're using exceptions improperly (e.g., to deal with non-bugs when you should be using the IF statement or checking it an iffy operation will work before you try it), this philosophy will fall apart more.
A side note, in thick client apps especially when there is the possibility of losing significant amounts or the users' input, you may be better with more try/catches where you attempt to save the data (marked as not-yet-valid of course).
EDIT: another need for at least having the logging routine in the PL - this will work differently depending on the platform. An app we're working on shares the BLL/DAL with 3 PL versions: an ASP.Net version, a winforms version, and a console app batch mode regression testing version. The logging routine that is called is actually in the BLL (the DAL only throws errors or totally handles any it gets or re-throws them). However this raises an event that is handled by the PL; on the web it puts it in the server's log and does web-style error message display (friendly message for production); in WinForms a special message window appears with tech support info, etc. and logs the error behind the scenes (developers can do something 'secret' to see the full info). And of course in the testing version it is a much simpler process but different as well.
Not sure how I'd have done that in the BLL except for passing a parameter 'what platform,' but since it doesn't include winforms or asp libraries that the logging depends on, that still would be a trick.
The layer that knows what to do to set things right should be the layer that handles the exception.
For example, if you decide to handle deadlock errors by retrying the query a certain number of times, then you could build that into your DAL. If it continues to fail, then you might want to let the exception bubble up to the next layer, which can then decide if it knows how to properly handle this exception.
All layers in your application should manage exceptions gracefullly. This is know as a cross cutting corncern, because it appears in all your layers.
I belive that using a framework like Enterprise Exception Block with unity, you will end up with a better code overall.
Take a look at this post
http://msdn.microsoft.com/en-us/library/ff664698(v=PandP.50).aspx
It will take sometime to master it, but there are lots of examples and screencast around there.
How to handle exceptions depends on technical and business needs. For complex or highly important database updates I include out params that pass a small list of known errors backup to the DL. This way, known error scenarios can be programmatically solved in some cases. In other cases the error needs to be logged and the user should be notified of an error.
I make a practice of notifying a human being of errors. Sure, logging will give us detailed information, but it's no replacement for the response time of a human being. Not only that, but why force developers to watch system logs just to see if things are going south? Talk about unnecessary cost.
If you have time to define potential errors/exceptions and programmatically solve them, then by all means do it. Many times errors/exceptions are unexpected. That's why it is important to be prepared for that unexpected and what better way to do that than involving a human being.
Overall, one should be on the defensive when planning exception handling. Programs grow or they die. A part of growing is introducing bugs. So don't spin your wheels trying to kill them all.
The question to you is where is the exception relevant? If it is a data access exception it should be caught in the DAL. If it is a logic exception it should be caught in the BLL. If it is a presentation exception then in the PL.
For instance if your DAL throws an exception it should return a null or a false or whatever the case may be to your BLL. Your BLL should know what to do if the DAL returns a null, maybe it passes it right through, maybe it tries calling another function, etc. The same goes with your PL if the BLL passes through a null from the DAL or returns something specific of its own then the presentation layer should be able to notify the end user that there was an issue.
Of course you won't get the verbose exception messages, but that is a good thing as far as your users are concerned. You should have a flexible logging system to catch these exceptions and report them to a database or an ip:port or whatever you decide.
Essentially you need to think in terms of separation of concerns if the concern is a data issue or a logic issue it should be handled accordingly.
So I am sold on the concept of attempting to collect data automatically from a program - i.e., popping up a dialog box that asks the user to send the report when something goes wrong.
I'm working in MS Visual Studio C#.
From an implementation point of view, does it make sense to put a try/catch loop in my main program.cs file, around where the application is run? Like this:
try
{
Application.Run(new myMainForm());
}
catch (Exception ex)
{
//the code to build the report I want to send and to
//pop up the Problem Report form and ask the user to send
}
or does it make sense to put try/catch loops throughout pieces of the code to catch more specific exception types? (I'm thinking not because this is a new application, and putting in more specific exception catches means I have an idea of what's going to go wrong... I don't, which is why the above seems to make sense to me.)
-Adeena
I think you are right, you would not know what's going to go wrong, which is the point.
However, you might as well consider adding a handler to the ThreadException event instead.
The code above will work but there will be scenarios where multi threading might be an issue with such code, since not all code inside your windows forms program will be running in the main Application.Run loop thread.
Here's a sample code from the linked article:
[STAThread]
static void Main()
{
System.Windows.Forms.Application.ThreadException += new ThreadExceptionEventHandler(ReportError);
System.Windows.Forms.Application.Run(new MainForm());
}
private static void ReportError(object sender, ThreadExceptionEventArgs e)
{
using (ReportErrorDialog errorDlg = new ReportErrorDialog(e.Exception))
{
errorDlg.ShowDialog();
}
}
More documentation on MSDN.
On a minor point, using the ThreadException event also allow your main message loop to continue running in case the exception isn't fatal (i.e. fault-tolerance scenarios) whilst the try/catch approach may requires that you restart the main message loop which could cause side effects.
From an implementation point of view, does it make sense to put a try/catch loop in my main program.cs file, around where the application is run?
Sure and always.
You should use Try/Catch-Blocks wherever you do something critical, that might raise an exception.
Therefore you can not really stick to a pattern for that, because you should now, when what exception will be raised. Otherwise these are unhandled exceptions, which let your program crash.
But there are many exceptions, that need not to stop the application entirely, exceptions, that just can be swallowed over, as they are expected and do not critically need the application to stop. Example for that are UnauthorizedAccessExceptions when moving or accessing data with your programm.
You should try to keep you Try/Catch-Blocks as small as needed, as well as to use not too much of them, because of performance.
Some out there use Try/Catch for steering the program's execution. That should entirely be avoided wherever possible, cause raising an Exception is performance killer number 1.
Wrapping a try catch around the whole application will mean the application will exit upon error.
While using a try and catch around each method is hard to maintain.
Best practice is to use specific try catches around units of code that will throw specific exception types such as FormatException and leave the general exception handling to the application level event handlers.
try
{
//Code that could error here
}
catch (FormatException ex)
{
//Code to tell user of their error
//all other errors will be handled
//by the global error handler
}
Experience will tell you the type of things that could go wrong. Over time you will notice your app often throwing say IO exceptions around file access so you may then later catch these and give the user more information.
The global handlers for errors will catch everything else. You use these by hooking up event handlers to the two events System.Windows.Forms.Application.ThreadException (see MSDN) and AppDomain.UnhandledException (see MSDN)
Be aware that Out of Memory exceptions and StackOverflowException may not be caught by any error catching.
If you do want to automatically get stack traces, Microsoft do allow you to submit them via the Error Reporting Services. All you need to do is sign up for a Digital Certificate from VeriSign and register it (for free) with Microsoft.
Microsoft then gives you a login for you to download the mini-dumps from a website, which are submitted when a user clicks "Send Error Report".
Although people can hit "Don't Send", at least it is a Microsoft dialog box and possibly not one that you have to code yourself. It would be running 24/7, you wouldn't have to worry about uptime of your web server AND you can submit workaround details for users AND you can deliver updates via Windows Update.
Information about this service is located in this "Windows Error Reporting: Getting Started" article.
The best approach is to sing up for
AppDomain.UnhandledException and Application.ThreadException In your application's main function. This will allow you to record any unhandled exceptions in your application. Wraping run in a try catch block does not catch every thing.
if you just want to capture crashes, then ignore all errors and let DrWatson generate a minidump for you. Then you can look at that ina debugger (windbg is preferred for minidumps) and it'll show you the line your code went wrong on, and also all the parameters, stack trace, and registers. You can set Drwatson to generate a full dump where you'll get an entire memory core dump to investigate.
I wouldn't recommend putting a try/catch around the entire app unless you want your app to never "crash" in front of the user - it'll always be handled, and probably ignored as there's nothing you can do with the exception at that point.
Sending the minidump to you is another matter though, here's an article, you'll have to do some work to get it sent via email/http/ftp/etc.