A process runs that parses many xml files, and within each file there are many nodes that represent work to be done.
Currently, errors that occur are logged to log4net one at a time, logging to a file once per error, and also generating an email once per error. This is not ideal, so I'm working to roll up all the errors that occur during one parsing session so they can be sent as a single email. For example, let's say the creator of the files accidentally left a crucial field out of each work node. Instead of 4,000 emails, I'd like to send a single email with 4,000 results, plus a summary at the top saying "4,000 field missing errors" and so on.
The trick comes when dealing with exceptions, because I don't know in advance what exception will occur. So, the previous state of the system worked well for tolerating exceptions because it flushed its knowledge as soon as it acquired it (sent an email, for example). But now I'm seeing that waiting until the end to send the email risks not sending an email at all. Let's say the nature of a repeating error is such that eventually it causes a system-level exception. By losing any error reporting at all, I never get the information on the repeating error that (almost certainly) led up to the big crash.
How can I get the best of both worlds, where logging is saved until the end, but whatever work is done and whatever information is collected has a decent chance of being logged even if an error occurs?
One thought I had was sending log information to a custom log4net appender that does caching or batching, and thus allows modification of the log message over time until it is finally triggered to be sent/logged (perhaps accepts individual items and a lambda that it executes at the end to assemble those items into a loggable result). Then, in my application:
var loggingContext = CreateNewLoggingContext();
try {
// Note: all reasonable and known or handleable exceptions will be
// caught from within this message. We're talking unforeseen or
// difficult to handle errors, here.
ParseAndProcessABunchOfFiles(loggingContext);
// within this method repeatedly use loggingContext.Push("error id", "error message");
}
catch (Exception e) {
loggingContext.Push("System-level exception", e);
loggingContext.Flush();
throw;
}
loggingContext.Flush();
But I am not particularly excited about catching every exception. An OutOfMemoryException is going to make it pretty hard to do an operation such as logging that might require even more memory. Or a disk full exception is going to make it hard to add to the log file on disk (though it would be grand if it still tried to run its email result and perhaps also log to the database).
How can I achieve these goals in a reasonable way?
UPDATE
Part of what's troubling me is distinguishing at each level in the call stack what is a recoverable error and what's one that should terminate the whole process. I guess what I have to do is simply catch the ones I can think of and reasonably expect, then as other exceptions show up, add specific handling for them.
Related
Usually, when I work with files and directories and I want to check that a path of a a directory or a file exists, I just use something like that:
if (Directory.Exists(path))
{
//Something...
}
However, if I understood this answer correctly, it is recommended to allow the exception still be thrown, meaning that rather than using if, use try.. catch.
Is that a general approach when working with files and directories or there are times that it is preferable using if(Directory.Exists... or something of that sort?
NOTE: After seeing the first responses, just wanted to clarify that the cases when certain directory/path might not exist is an expected and normal behavior.
You nearly always have to catch exceptions, especially for I/O errors, somewhere, lest the program simply be killed when one occurs.
In many scenarios, it makes sense to also first check for valid input (e.g. Directory.Exists()). This allows you to efficiently and in a user-friendly way report and respond to obvious user-error scenarios.
But you have no guarantee that the directory won't be deleted between the time you execute that call and the time you try to access it in some way. Or that if the directory is on a remote share, the network won't fail. Or that you won't have some other kind of I/O error.
There are a few exceptions that just aren't worth catching. Unexpected OutOfMemoryException for example (as opposed to some data structure simply getting too large), or other types of internal .NET failures. The likelihood of recovering from those types of errors is minimal. But for anything else, you at some point should be catching exceptions that could happen. Sometimes this simply means a top-level catch (Exception e), where you will log the exception in some way before exiting the program cleanly.
(I will note that exceptions that are uncaught and which cause the application to be terminated will generally get logged in the system event log. So as long as users are comfortable inspecting the log and retrieving exception information from there, then there's no need to catch all exceptions…just those you know what to do with).
100% depends on what you want to achieve.
If a path is invalid and you want to inform it to the user, you can choose between returning a success value or throwing an exception by what's more suitable for your code architecture.
In other cases, where something can go wrong without the user being responsible for it, or needing to be informed, you usually let exceptions get thrown and handle them in catch blocks in the appropriate places.
The thing to remember is that you can always perform an if check and throw an exception of your own in case of invalid state, rather than letting the invalid state cause an exception by itself. The main difference there is in the data thrown with the exception (stack trace, message, etc), but can also be expressed in performance (you wouldn't want to try a high-cost operation if you can first perform a low-cost check to make sure it will succeed). Try-catch blocks add a BIT of an overhead as well, but I wouldn't consider that to be significant.
The questions to ask are:
Does invalid state causes the whole operation from above to fail?
Where and how does the code handle invalid state?
Does the code "fix" the invalid state and tries again?
Is the invalid state originating from a user error or a code issue?
How costly the operation is, in contrast to how costly the validation check is?
Edit: Check out Yuval's link in the comment to get better understanding of the costs of try-catch blocks.
The validation check is almost always very low-cost, so in conclusion I would say: Perform the check, even if you intend to throw your own exception in case of invalid state.
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.
First, I'm already familiar with the simple exception handling syntax but I'm asking about the best place, the best time and the best way to deal with them.
I'm building an N-Layered application. so I think the DAL will sometime generate some errors to handle .. and I just learned about the SqlException class, what's the deal with that class ? I once saw a code that handles the SqlException then it handles Exception!
After knowing the practice and where I'm going to handle them, I'm planning to create a method to connect to the database and log the errors in a database so I could fix it but still I don't know what information should I collect to allow me identify the whole situation!
I thought exceptions handling was not a big deal. but every now and then I read some strange advices -that I never understood- on the questions comments but no one could answer me since it was some very old questions!
"Don't just explicitly catch
exceptions"
"the code that is used by
higher-layers in your application must
always only throw exceptions and never
worry about how to deal with them."
EDIT
What about Page_Error event and Application_Error .. I saw that they are a good practice for handling errors
Exception handling is a big deal, and it's not simple to design a good strategy for that.
First of all, some general rules:
Exceptions occur when the running code is completely unable to go ahead, so maybe it tried to handle some internal exceptions but ultimately failed. Think about TCP connection: if a damaged packet arrives, it's an exception, but TCP protocol can handle it. If too many are damaged, an I/O or socket exception is thrown
Exceptions can not always be handled. In almost all cases, when you get an exception from underlying layers you are unable to run corrective code. If your application depends on a DB and that is offline, when you get the exception about it you can only display an error message
Exceptions can be unexpected, and can reveal design or implementation flaws. For example, an implementation flaw can be the situation in which you have a redundant DB but when you fail to connect to frist mirror you don't try with the second
For the third point, it's important to log exceptions and periodically analyse logs to find any weird situation. So, let's begin with the concrete answer.
First of all
think about "handling" the exception. When you write every single code line, think about the possible problems that may prevent it from completing, and think about the possible corrective actions. if any are possible. An error message is not a good handling way, it's the latest strategy.
Don't start to write try-catch(Exception), but prefer specific exceptions. If you need to parse strings to numbers etc, then expect FormatException, if you need to cast from Object to your type expect InvalidCastException
When you write lower-level layers
don't hesitate to throw exceptions!! Don't do like many folks do, ie. return null or use (like ANSI C) a boolean return value and reference parameters. Exceptions are there for that. If you can handle an exception (ie. you don't find a local file but you know you have a remote backup, so handle FileNotFoundException by calling the remote mirror, but if you can't still connect then ultimately throw) then do it and try to resume computation, but if you cannot then throw. And don't forget to throw the inner exception, if present, because it is helpful for logging in the highest layer.
Basically, you can still decide to throw an exception on your own even if you don't catch any! And this is highly recommended especially when function parameters are invalid!
Another good option is to still log in the underlying layers. You actually want to log no matter an exception occurs.
When you log
remember to give an adequate severity to the messages. If you find via code that your DB is offline, that's not an unexpected exception. Still log it as an error, but don't worry about code bugs when you investigate the logs. Instead, if you catch an exception that your code is unable to recognize (a NullReferenceException is a classic example) then log with highest severity, ie. fatal, to give it maximum priority!
A good strategy for ASP.NET
can surely be based upon Page.OnError method. If you have a base page class for all of the pages of your site, you should definitely override that method. In that method, you should first log your exception.
You also shouldn't abuse of try-catch(Exception) blocks, because if you don't catch an exception you can't handle with catch, you will have to handle it via OnError.
When you run such a method, don't immediately think about Server.RemoveError(). You can prefer to have a static HTML page for HTTP 500 error (that is triggered when an unhandled exception bubbles to ASP.NET runtime) that displays a courtesy message to the user.
Briefly
Don't hesitate to throw in underlying layers if anything strange occurs
As said by your advice, don't handle exceptions you are unable to handle (if you catch an exception you can't handle, rethrow it)
LOG!!!!!!!!!!!!!!!!!
Don't disclose exception details to final users on a public website, never!! By default, ASP.NET prevents that from occurring, but you could still use OnError to print stack trace
Use OnError, or Application_Error as single central point to handle all unexpected exceptions
Periodically examine logs against error/fatal messages to find issues with your code, then think about maintaining/debugging/fixing it
Take a look at elmah. It's a logger for asp.net. Renders all errors on a nice summary page.
http://code.google.com/p/elmah/
The best way to handle exceptions is in the specific layer they apply to. If it is a constraint volation, for example, 2 users with the same name, you should let that bubble up to the UI and alert the user.
Same goes with any business rule violations. Those should bubble up to the UI so the end user knows what went wrong.
A SQL Connectivity error is best handled in the DAL...etc..
The how/when/where to catch exceptions may depend on what your trying to do exactly, its difficult to give an exact catch all always correct answer.
As to your specific questions,
I just learned about the SqlException
class, what's the deal with that class
? I once saw a code that handles the
SqlException then it handles
Exception!
Its good practice to handle the specific exception you believe may occur, if your not sure what type this exception is you can just 'Exception', if you want something specific to occur on a 'SQLException' and something else to happen with an 'Exception' then there is certainly nothing wrong with writing code that handles both.
"Don't just explicitly catch
exceptions"
I believe this is refering to code like this
try
{
int i = 1/0;
}
catch(Exception e)
{
//do nothing
}
This exception will be caught but you'll never know it happened, hence this is not a good idea, and the person using the code will be scratching their head as to whats going on.
I think what you are asking here is a Error/Exception Handling Strategy for any application.
I think it includes:
Where - All places where you think an exception can occur or which need more monitoring like DB calls, External Service Calls, Use of Arrays, User Input Parsing, Type Casting and so on...
How - All you high level layers should throw the exception and it should be captured at the entry point and processed to understand the root cause. Usually you do this in Application_Error() where you catch the exception and log it for troubleshooting. How you log an exception is upto you. A Log File or DB driven log is an option based on your requirements and available resources.
IMO apart from extremely rare circumstances I only ever use exception handling for I/O related code where there are interactions with services and file systems whose functionality and maintenance is beyond the control of my applications.
I have always considered the use try/catch statements to manipulate the logic (flow-of-control) in a program in the same way if/else statement work to be extremely bad practice. Most common exceptions can be avoided if you use the tools at hand correctly.
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.
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.