In my application i have 100 classes and each class contains 4 methods each.
I am using try catch for exception handling. I write try catch in each method , then there will be 400 try catch statement in my application. Is it affect the performance of my application? Is it possible to handle the whole exception using one try catch statement in the whole application?
Do you need to handle exceptions within each method? Typically that's not the way things work - in my experience, most exceptions can't really be handled in a better way than telling the user something went wrong and aborting the higher-level action, which could involve a stack of several methods.
So normally you'll have a very few try/catch blocks at the "top" level, and the methods doing most of the work will just let the exceptions bubble up.
there will be 400 try catch statement in my application
That is completely unnecessary and in fact bad, making your code overcomplicated and inefficient. Catch exceptions only where you can actually handle them.
Is it possible to handle the whole exception using one try catch statement in the whole application?
That would usually be the other extreme. Try to find the middle ground, identifying the places where you can meaningfully handle specific exceptions by e.g. logging, displaying an appropriate error message on the GUI, retrying the problematic action in a different way etc. If you are tempted to wrap an exception into a new, different exception and throw that to a higher level, it is often a sign that you may be catching it on too low a level. (The exception is when you need to encapsulate exceptions thrown by some lower level API to avoid dependencies.)
Catch exceptions as local as you're willing and able to handle them. A mere try/catch will not affect performance (it's just a jump target, after all), and if at all, then negligible. If exceptions get thrown then you'll have a performance hit, since exceptions are quite slow. But apart from that, no.
You should not use try-catch anywhere in the class if that is behaving like a class library, use try-catch where you are calling functions. That way it will be more managible and makes sense
If you have a large application and want not to clutter your code with try catch you might consider using Enterprise Library Exception Handling Application Block
Instead of repeating this code (such as code
that logs exception information) in identical catch blocks throughout
an application, the Exception Handling Application Block allows
developers to encapsulate this logic as reusable exception handlers.
Usually exceptions should be categorized at the lower levels of the application and re-thrown onto the upper levels, for example if it's a invalidity of business logic (say price of a product calculated as negative) is desired to categorized as different type of exception while error data loading should be categorized as some other type. Based on the type the exceptions can be handled in the top layer and depending on the type of error user can be informed what sort of action to be taken.
Related
Recently I have used Global exception handling in my code and I came to know that with this all exceptions can be handled. Previously I was using try-catch at each controller and now I have removed all the try-catch from controller because of Global exception as it can handle all types of exception.
So I doubt that, is it a good practice to remove all the exception handling I have previously used in the controller for Global Exception handling or should use both Global, as well as try-catch at the controller.
And if try-catch is required, is it necessary that all the exceptions are to be handled at the controller level.
My current working stack is - .Net Core.
The question is too broad to give a full answer but, let me give my opinion on this matter.
try-catch-finally blocks are not used to handle unhandled exceptions. Naturally the cases that you never thought of will be unhandled and you should not keep them silent but you should allow them to express themselves for you to think about them. Handled exceptions though are the cases that are not at the hand of the programmer but he/she has thought about them. For example user input is string instead of number.
If it's the case that you thought but is in your control always check with ifs. For example if something can be null. Try-catch is really costly and no logic should be handled in them.
Using a global exception handler on the other hand is the exact opossite. It is not to wrap all thought cases and show a single response to user. You should log unknown exceptions to come back and think about why they happened and in the mean time say that you are sorry to user. :)
I have a question reagrding proper programming practice when dealing with exceptions.
We have production code like:
try
{
File.Copy(src,dest);
}
catch(Exception ex)
{
ShowMessageToUser(ex.Message);
}
Is this a good practice? I thought that we should always make use of specialized exceptions and catch them....on the other hand, I do realize that File.Copy can throw several different exceptions and it will be a pain to write a catch block for every exception...? So what should be done in this case....Is there a set of file specific excepion collections that we can use to catch?
Thanks , any comments are welcome.
As a general practice, I would say this is not a good practice. Personally, I would handle this with separate exceptions, and only handle the exceptions you can be handle correctly.
In this specific scenario, I would also avoid this. I would prefer to handle the explicit exception types, if for no other reason than to customize the message to the user.
This is mainly because exception messages are really not intended for an end user - they're messages meant to be interpreted by a developer. I feel that directly showing an exception message to a user, especially for an operation where an exception is likely, is a bad practice.
You should handle each exception, and provide a meaningful message to the user that makes sense in the context of this operation.
File.Copy can only throw 8 types of exceptions - handling every one, with a message, is only 32 lines of code - that's really not that much when you consider the extra benefit of having a clear, meaningful message in all cases presented to the end user.
IO is generally a pain for this reason- there are so many things that can go wrong. It would be best for you to:
Do everything you can to avoid exceptions by checking all parameters before calling File.Copy. Remember that in .Net exceptions can have severe performance costs due to the generation of a stack trace.
Catch the exceptions that you know you are capable of handling. For some exceptions you might want to display an error message and ask the user for new input.
If you can't handle an exception right there, do not catch it! Exception swallowing is the source of all evil. Reporting an error message is only slightly better than exception swallowing and will only confuse the end user.
It may seem like a lot of work, but sometimes a lot of work is necessary to produce a stable program.
You use specialized exceptions in order to perform different actions based on the type of error you got. If all you want is to show the user the default error message... then your code is sufficient.
But let's say for example that you would like to log the exception if it happened because of security issues... you would write something like:
catch (PermissionDeniedException ex)
{
Log(ex.foo);
ShowMessageToUser(ex.Message);
}
catch(Exception ex)
{
ShowMessageToUser(ex.Message);
}
And remember to always go from more specific to more general exceptions.
Yes that's a bad Practice and you should use specific Exceptions and then general Exception lower the catch block.
If you feel that they are too many then you should at least create catch blocks for most Anticipated file Specific Exception and then have usual Exception catch block
Your example is very easy to implement, but hardly best practices. As a general rule
Only catch Exceptions you are actually interested in handling at this point. Let everything else bubble on to be handled elsewhere.
You can also use superclasses to catch a specific group of exceptions.
Do not use exceptions for things that are not errors. For example, if the user supplies the file name for the copy, you can check beforehand if the file exists, instead of relying on an exception. Exceptions are for "exceptional circumstances", not for foreseeable conditions.
If you're hacking a quick script, however, feel free to use the exception as in your example ;-)
I’m used to having try/catch blocks in every method. The reason for this is so that I can catch every exception at the point of infraction and log it. I understand, from my reading and conversations with others, that this isn’t a popular view. One should only catch what one is prepared to handle. However, if I don’t catch at the point of infraction, then it would be possible to never log that infraction and know about it. Note: When I do catch and don’t handle, I still throw. This allows me to let the exception propagate to something that will handle it, yet still let me log it at the point of infraction.
So... How does one avoid try/catch in every method, yet still log the error at the point at which it occurred?
No, don't catch everything. Exceptions propagate higher up on the stack. All you have to do is make sure that the exception is caught before it gets to the top of the stack.
This means, for instance, that you should surround the code of an event handler with a try/catch block. An event handler may be the "top of the stack". Same for a ThreadStart handler or a callback from an asynchronous method.
You also want to catch exceptions on layer boundaries, though in that case, you might just want to wrap the exception in a layer-specific exception.
In the case of ASP.NET, you may decide to allow ASP.NET Health Monitoring to log the exception for you.
But you certainly don't ever need to catch exceptions in every method. That's a major anti-pattern. I would loudly object to you checking in code with that kind of exception handling.
You can see everything at stack trace - no need to try/catch every method.
Stick to few rules:
Use try/catch only if you want to use a custom exception type
Define a new exception type only if upper levels needs to know that
Try/catch at top level instead of doing that for each method
OK, having read all the answers saying you should have a single try/catch at the top level, I'm going to weigh in with an alternative view.
I wouldn't put a try/catch in every method, far from it. But I would use a try/catch around sections of code that I expected to fail (e.g. opening a file), and where I wanted to add additional information to the exception (to be logged higher up the chain).
A stack trace saying and a message saying "permission denied" might be enough to allow you as a programmer to figure out what went wrong, but my goal is to provide the user with meaningful information, such as "Could not open file 'C:\lockedfile.txt'. Permission denied.".
As in:
private void DoSomethingWithFile(string filename)
{
// Note: try/catch doesn't need to surround the whole method...
if (File.Exists(filename))
{
try
{
// do something involving the file
}
catch (Exception ex)
{
throw new ApplicationException(string.Format("Cannot do something with file '{0}'.", filename), ex);
}
}
}
I'd also like to mention that even the people saying "only have one try/catch" would presumably still use try/finally throughout their code, since that's the only way to guarantee proper cleanup, etc.
Catching and rethrowing an exception that you cannot handle is nothing more than a waste of processor time. If you can't do anything with or about the exception, ignore it and let the caller respond to it.
If you want to log every exception, a global exception handler will do just fine. In .NET, the stack trace is an object; its properties can be inspected like any other. You can write the properties of the stack trace (even in string form) to your log of choice.
If you want to ensure that every exception is caught, a global exception handler should do the trick. In point of fact, no application should be without one.
Your catch blocks should only catch exceptions that you know that you can gracefully recover from. That is, if you can do something about it, catch it. Otherwise, let the caller worry about it. If no callers can do anything about it, let the global exception handler catch it, and log it.
I definitely don't use a try catch wrapper around every method (oddly enough, I did when I first started but that was before I learned better ways).
1) To prevent the program from crashing and the users losing their info, I do this
runProgram:
try
{
container.ShowDialog();
}
catch (Exception ex)
{
ExceptionManager.Publish(ex);
if (MessageBox.Show("A fatal error has occurred. Please save work and restart program. Would you like to try to continue?", "Fatal Error", MessageBoxButtons.YesNo) == DialogResult.Yes)
goto runProgram;
container.Close();
}
container is where my application starts so this basically puts a wrapper around my entire app so that nothing causes a crash that can't be recovered. This is one of those rare instances where I don't really mind using a goto (it is a small amount of code and still quite readable)
2) I only catch exceptions in methods where I expect something could go wrong (such as a timeout).
3) Just as a point of readibility, if you have a try catch block with a bunch of code in the try section and a bunch in the catch section, it is better to extract that code to a well named method.
public void delete(Page page)
{
try
{
deletePageAndAllReferences(page)
}
catch (Exception e)
{
logError(e);
}
}
To do it at the point of occurrence, you would still need a try/catch. But you don't necessarily need to catch the exceptions everywhere. They propagate up the call stack, and when they are caught, you get a stack trace. So if a problem emerges, you can always add more try/catches as needed.
Consider checking out one of the many logging frameworks that are available.
I don't think you need to catch everything at the point of infraction. You can bubble up your exceptions, and then use the StackTrace to figure out where the point of infraction actually occurred.
Also, if you need to have a try catch block, the best approach I've heard is to isolate it in a method, as to not clutter the code with huge try catch blocks. Also, make as few statements as possible in the try statement.
Of course, just to reiterate, bubbling up your exceptions to the top and logging the stacktrace is a better approach than nesting try-catch-log-throw blocks all throughout your code.
I would look into using ELMAH for exception handling, which is pretty much a concept of "let exceptions happen". ELMAH will take care of logging them and you can even set it to email you when exceptions for a certain project reach or exceed a specific threshold. In my department, we stay as far away from try/catch blocks as possible. If something is wrong in the application, we want to know right away what the issue is so we can fix it, instead of repressing the exception and handling it in code.
If an exception happens, that means that something isn't right. The idea is to make your application do only what it should do. If it's doing something different and causing exceptions, your response should be to fix the reason it's happening, not let it happen and handle it in code. This is just my/our philosophy and it's not for everyone. But we've all been burned way too many times by an application "eating" an exception for some reason or another and no one knows that something is wrong.
And never, ever, EVER catch a general Exception. Always, always, always catch the most specific exception so that if an exception is thrown, but it's not the type you're expecting, again, you'll know because the app will crash. If you just catch (Exception e), then no matter what type of exception is thrown, your catch block will now be responsible for responding to every single type of exception that could possibly be thrown. And if it doesn't, then you run into the whole "eating" exceptions, where something is going wrong but you never know until it is likely too late.
How does one avoid try/catch in every method, yet still log the error at the point at which it occurred?
It depends on the hosting env. Asp.Net, WinForms, and WPF all have different ways of capturing unhandled exceptions. But once the global handler is passes an exception instance you can determine the point of throw from the exception, as each exception includes a stacktrace.
Realistically, avoid granular try/catches. Allow the exception to traverse upwards in the stack and be caught in as high a level as possible. If you have a specific point of concern, then place logging in the immediate catch, if you are worried about the exception cascading - although you would still be able to resolve these by drilling into the inner exceptions.
Exception handling should not be an afterthought. Make sure that you do it consistently. I have seen a lot of people put a broad try/catch from the beginning to the end of every method and catch the general exception. People think that this helps them get more information, when in fact, it doesn't. More is less in some cases, as less is more. I never get tired of the axiom that "Exceptions should be used to note exceptional behavior." Recover if you can, and try to reduce the number of overall exceptions. Nothing is more frustrating when you are trying to troubleshoot an issue and seeing hundreds of the same NullReferenceException, or similar, when something goes wrong.
Exceptions are implemented so that they have no cost unless thrown.
This means to me that performance ramifications is not a strong argument against. Exceptional conditions usually are ... exceptional.
This question already has answers here:
Best practices for catching and re-throwing .NET exceptions
(11 answers)
Closed 9 years ago.
I'm wondering what the correct way is to pass on an exception from one method to another.
I'm working on a project that is divided into Presentation (web), Business and Logic layers, and errors (e.g. SqlExceptions) need to be passed down the chain to notify the web layer when something goes wrong.
I've seen 3 basic approaches:
try
{
//error code
}
catch (Exception ex)
{
throw ex;
}
(simply rethrow)
try
{
//error code
}
catch (Exception ex)
{
throw new MyCustomException();
}
(throw a custom exception, so that a dependency on the data provider is not passed on)
and then simply
//error code
(not doing anything at all, letting the error bubble up by itself)
Naturally there's some logging happening in the catch block too.
I prefer number 3, while my colleague uses method 1, but neither of us can really motivate why.
What are the advantages/disadvantages of using each method? Is there a better method I don't know of? Is there an accepted Best Way?
If you do nothing you should simply let it go upper where some one will handle it.
You can always handle a part of it (like logging) and re-throw it. You can re-throw by simply sending throw; without having to explicit the ex name.
try
{
}
catch (Exception e)
{
throw;
}
The advantage to handle it is that you can ensure that some mechanism is there to notify you that you have an error where you do not suspect to have one.
But, in some case, let say a Third Party, you want to let the user handle it and when it's that case you should let it continue to bubble up.
I think you should start with a slightly different question
How do I expect other components to interact with exceptions thrown from my module?
If the consumers are quite capable of handling the exceptions thrown by the lower / data layers then quite simply do nothing. The upper layer is capable of handling the exceptions and you should only do the minimum amount necessary to maintain your state and then rethrow.
If the consumers cannot handle low level exceptions but instead need a bit higher level exceptions, then create a new exception class which they can handle. But make sure to pass on the original exception a the inner exception.
throw new MyCustomException(msg, ex);
The correct way to re-throw an exception in C# is like below:
try
{
....
}
catch (Exception e)
{
throw;
}
See this thread for specifics.
Only use try/catch blocks around exceptions you expect and can handle. If you catch something you cannot handle, it defeats the purpose of try/catch which is to handle expected errors.
Catching big exception is rarely a good idea. The first time you catch an OutOfMemoryException are you really going to be able to gracefully handle it? Most API's document the exceptions each method can throw, and those should be the only ones handled and only if you can gracefully handle it.
If you want to handle the error further up the chain, let it bubble up on its own without catching and rethrowing it. The only exception to this would be for logging purposes, but logging at every step is going to do an excessive amount of work. It is better to just document where exceptions your public methods can be expected to allow to bubble up and let the consumer of your API make the decision on how to handle it.
No one has yet pointed out the very first thing you should be thinking of: what are the threats?
When a back-end tier throws an exception, something terrible and unexpected has happened. The unexpected terrible situation might have happened because that tier is under attack by a hostile user. The last thing you want to do in that case is serve up to the attacker a detailed list of everything that went wrong and why. When something goes wrong on the business logic tier the right thing to do is to carefully log all information about the exception and replace the exception with a generic "We're sorry, something went wrong, administration has been alerted, please try again" page.
One of the things to keep track of is all the information you have about the user and what they were doing when the exception happened. That way if you detect that the same user always seems to be causing problems, you can evaluate whether they are likely to be probing you for weaknesses, or simply using an unusual corner of the application that wasn't sufficiently tested.
Get the security design right first, and only then worry about diagnosis and debugging.
I've seen (and held) various strong opinions about this. The answer is that I don't think there currently is an ideal approach in C#.
At one point I felt that (in a Java-minded way) the exception is part of the binary interface of a method, as much as the return type and parameter types. But in C#, it simply isn't. This is clear from the fact that there is no throws specification system.
In other words, you can if you wish take the attitude that only your exception types should fly out of your library's methods, so your clients don't depend on your library's internal details. But few libraries bother to do this.
The official C# team advice is to catch each specific type that might be thrown by a method, if you think you can handle them. Don't catch anything you can't really handle. This implies no encapsulation of internal exceptions at library boundaries.
But in turn, that means that you need perfect documentation of what might be thrown by a given method. Modern applications rely on mounds of third party libraries, rapidly evolving. It makes a mockery of having a static typing system if they are all trying to catch specific exception types that might not be correct in future combinations of library versions, with no compile-time checking.
So people do this:
try
{
}
catch (Exception x)
{
// log the message, the stack trace, whatever
}
The problem is that this catches all exception types, including those that fundamentally indicate a severe problem, such as a null reference exception. This means the program is in an unknown state. The moment that is detected, it ought to shut down before it does some damage to the user's persistent data (starts trashing files, database records, etc).
The hidden problem here is try/finally. It's a great language feature - indeed it's essential - but if a serious enough exception is flying up the stack, should it really be causing finally blocks to run? Do you really want the evidence to be destroyed when there's a bug in progress? And if the program is in an unknown state, anything important could be destroyed by those finally blocks.
So what you really want is (updated for C# 6!):
try
{
// attempt some operation
}
catch (Exception x) when (x.IsTolerable())
{
// log and skip this operation, keep running
}
In this example, you would write IsTolerable as an extension method on Exception which returns false if the innermost exception is NullReferenceException, IndexOutOfRangeException, InvalidCastException or any other exception types that you have decided must indicate a low-level error that must halt execution and require investigation. These are "intolerable" situations.
This might be termed "optimistic" exception handling: assuming that all exceptions are tolerable except for a set of known blacklisted types. The alternative (supported by C# 5 and earlier) is the "pessimistic" approach, where only known whitelisted exceptions are considered tolerable and anything else is unhandled.
Years ago the pessimistic approach was the official recommended stance. But these days the CLR itself catches all exceptions in Task.Run so it can move errors between threads. This causes finally blocks to execute. So the CRL is very optimistic by default.
You can also enlist with the AppDomain.UnhandledException event, save as much information as you can for support purposes (at least the stack trace) and then call Environment.FailFast to shut down your process before any finally blocks can execute (which might destroy valuable information needed to investigate the bug, or throw other exceptions that hide the original one).
I'm not sure that there really is an accepted best practices, but IMO
try // form 1: useful only for the logging, and only in debug builds.
{
//error code
}
catch (Exception ex)
{
throw;// ex;
}
Makes no real sense except for the logging aspect, so I would do this only in a debug build. Catching an rethrowing is costly, so you should have a reason for paying that cost other than just that you like looking at the code.
try // form 2: not useful at all
{
//error code
}
catch (Exception ex)
{
throw new MyCustomException();
}
This one makes no sense at all. It's discarding the real exception and replacing it with one that contains less information about the actual real problem. I can see possibly doing this if I want to augment the exception with some information about what was happening.
try // form 3: about as useful as form 1
{
//error code
}
catch (Exception ex)
{
throw new MyCustomException(ex, MyContextInformation);
}
But I would say in nearly all cases where you are not handling the exception the best form is to simply let a higher level handler deal with it.
// form 4: the best form unless you need to log the exceptions.
// error code. no try - let it percolate up to a handler that does something productive.
Normally you'd catch only exceptions which you expect, can handle and let application work in a normal way further. In case you'd like to have some additional error logging you'll catch an exception, do logging and rethrow it using "throw;" so the stack trace is not modified. Custom exceptions are usually created for the purpose of reporting your application specific errors.
Should I always wrap external resource calls in a try-catch? (ie. calls to a database or file system) Is there a best practice for error handling when calling external resources?
Catch only exceptions that you can handle. So for example when using external resources, the best practice is to catch specific exceptions that you know you can handle. In case of files this can be (IOException, SecurityException, etc), in case of Database the exception can be SqlException or others.
In any case, don't catch exceptions that you don't handle, let them flow to a upper layer that can. Or if for some reason you do catch exceptions but don't handle them, rethrow them using just throw; (which will create an rethrow IL op, as opposed to trow).
In case of using resources that you don't know what type of exceptions might throw, you are kind of forced to catch the general exception type. And in this case the safes thing would be to use the said resources from a different app domain (if possible), or let the exception bubble up to top level (ex UI) where they can be displayed or logged.
I think there are three reasons to have a catch block:
You can handle the exception and recover (from "low level" code)
You want to rewrap the exception (again, from "low level" code)
You're at the top of the stack, and while you can't recover the operation itself, you don't want the whole app to go down
If you stick to these, you should have very few catch blocks compared with try/finally blocks - and those try/finally blocks are almost always just calling Dispose, and therefore best written as using statements.
Bottom line: It's very important to have a finally block to free resources, but catch blocks should usually be rarer.
> Know when to set up a try/catch block. For example, you can programmatically check for a condition that is likely to occur without using exception handling. In other situations, using exception handling to catch an error condition is appropriate.
That's what I found and it makes sense to me.. Check manually for the obvious things, let try-catch do the rest..
Eric Lippert has a good blog on this, here.
There is no point (except for "vexing" (see blog)) catching an exception unless you can do something useful; and in most cases you simply can't - so let it bubble (your UI should obviously cleanse and display something).
You might, however, have a "try/finally" to deal with resource management. Or even cleaner, a "using" block to do the same.
I think the absolute answer is completely conditional (how control do you have over the environment, what is the expected balance between performance and consistency and many others I'm sure), but generally speaking I always do, choosing the safety over the potentially slower performance.
it always depend on what you want to achieve. A server not responding might be serious enough to stop all what the routine what doing, and the exception should be thrown to the caller.
In other cases, you don't care whether you failed to update the db or not. Then consuming the exception is OK.
Obviously, you don't want to show the stack trace to your end user, though, so you'll need to catch it somewhere.