I know that there are some exception types that cannot be caught in catch blocks, like StackOverflowException in .NET 2.0. I would like to know which other exceptions are inadvisable to catch, or are associated with bad practices.
The way I would like to use this list of exception types is to check it every time I am using Exception in a catch block:
private static readonly Type[] _exceptionsToNotCatch = new Type[] { typeof(StackOverflowException) };
// This should never throw, but should not swallow exceptions that should never be handled.
public void TryPerformOperation()
{
try
{
this.SomeMethodThatMightThrow();
}
catch (Exception ex)
{
if (_exceptionsToNotCatch.Contains(ex.GetType()))
throw;
}
}
EDIT
I don't think I provided a very good example. That's one of the problems with trying to make an example trivial when trying to communicate one's meaning.
I never throw Exception myself, and I always catch specific exceptions, only catching Exception as follows:
try
{
this.SomeMethodThatMightThrow();
}
catch (SomeException ex)
{
// This is safe to ignore.
}
catch (Exception ex)
{
// Could be some kind of system or framework exception, so don't handle.
throw;
}
My question was meant as more of an academic one. What exceptions are only thrown by the system and should never be caught? I am worried about situations more like this:
try
{
this.SomeMethodThatMightThrow();
}
catch (OutOfMemoryException ex)
{
// I would be crazy to handle this!
// What other exceptions should never be handled?
}
catch (Exception ex)
{
// Could be some kind of system or framework exception, so don't handle.
throw;
}
This question was really inspired by the following:
System.Data.EntityUtil.IsCatchableExceptionType(Exception) in System.Data.Entity, Version=3.5.0.0
I would like to know which other exceptions are inadvisable to catch, or are associated with bad practices.
Here is the list of all exceptions you shouldn't catch:
Any exception you don't know what to do with
Here's the best practice for exception handling:
If you don't know what to do with an exception, don't catch it.
This may sound snarky, but they're both correct, and that's all you need to know.
It's generally not a good idea to do that.
You should catch the most specific exception(s) possible and only carry on execution of your program when it is safe to do so. E.g. if you're opening a file, it's perfectly reasonable to catch exceptions relating to file access / permission errors, but probably not much else. You certainly wouldn't want to catch an OutOfMemoryException and then blindly carry on. They're very different errors!
If you apply a blanket rule of what to catch, there's no guarantee that your program will be able to continue execution safely because you're not responding to specific situations, just applying a one size does not fit all solution.
Using Exception in the catch block would catch all exceptions that are catchable. I would say you should specify only exceptions that needs to be caught and let the ones you don't want to catch spill out. E.g.
try
{
}
catch(SqlException sqlex) //specific to database calls
{
//do something with ex
}
catch(FormatException fex) //specific to invalid conversion to date, int, etc
{
//do something with ex
}
catch(Exception ex)
{
//I didn't know this exception would be thrown
//log it for me or Rethrow it
}
Any other exception not in that list will not be caught
Okay so we've established it ain't a good idea. And we've established that programmers on SO prefer to opine from their high-horses rather than hand you a knife to stab yourself with, so for those with suicidal tendencies, let's start with these:
(Redacted my list and DRYing-up SO to point to Hans' list)
https://stackoverflow.com/a/5508733/17034
Related
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why catch and rethrow Exception in C#?
I've been scouring the net trying to find the answer to this question - What's the between the two?
try
{
//Do Something
}
catch
{
throw;
}
vs
try
{
//Do Something
}
catch
{
}
or
try
{
//Do Something
}
catch (Exception Ex)
{
//Do something with Exception Ex
}
The first one rethrows the exception up the stack and preserves the stack trace.
The second one swallows (hides) the exception.
The third one probably also swallows the exception but it depends on what (//Do something) does.
catch --> throw will actually just throw your error, so you will have to catch it somewhere else. This can be useful if you want to catch something first and then throw the error to other methods above.
Example:
try
{
// do something
}
catch
{
Console.WriteLine("Something went wrong, and you'll know it");
throw;
}
// won't get here anymore, the exception was thrown.
While try --> catch will just let you ignore the error.
try
{
// do something
}
catch
{
Console.WriteLine("Something went wrong, and you won't know it.");
}
// continuing happily
The first one re-throws the same exception that was caught. the second one swallows the exception as if it never happened. So it depends on what you need.
Please note that there IS a difference between these two:
try
{
//Do Something
}
catch (Exception Ex)
{
//re-throws the same exception that was caught
throw;
}
try
{
//Do Something
}
catch (Exception Ex)
{
//throws a _new_ exception containing Ex
throw Ex;
}
In the first, you are just rethrowing the exception. You don't need try/catch in this case, because you aren't doing anything with the caught exception.
In the second, you are swallowing all exceptions. This is incredibly dangerous. Do not ever do this. It is never correct.
In the last, you haven't given us enough detail to know. You are catching the exception, and you might do something with it. You could rethrow, you could swallow. You haven't told us.
In the first block, an exception is thrown again inside of the handler for the first block. That means that it can be picked up by an outer-try/catch scope block. The second block "eats" the exception in the catch block, and program execution can continue normally after the code in the catch block is executed.
In the first case the exception is rethrown to the caller. This version is pointless because you do nothing with the exception but in practice you may do something and then throw the exception to the caller. It is also useful when filtering exceptions for example
try
{
//do somethign
}
catch(Exception1)
{
throw;
}
catch
{
//do something
}
The second is something you should never do. You are covering an exception and making it harder to catch eventual bug in your application. You either need to handle the exception in a meaningful way or let it break the program (or let the caller handle it)
The third example is simple exception handing. Make sure you don't use it as a form of if/else (flow control)
In cases when you use a try catch block as such.
try {
//Do my work!
}
catch
{
//Handle my exception
}
Is there some way to refer to the exception object in the catch block?
ie:
try {
//Do my work!
}
catch
{
//Handle my exception
MyUndefinedExceptionObject.Message ????
}
EDIT: I don't think I was clear
enough. I am aware of how one would
typically catch exceptions using a try
catch block. What I am wondering is
given you have the ability to not
specify a type for your exception yet
declare the block is there still some
way of retrieving the exception object
in such cases? Judging by your answers
however I assume there isn't?
You'll want to catch the exception type you care about. When you do, you'll have access to all the properties of that exception.
try
{
//Do my work!
}
catch (MyExceptionType e)
{
string s = e.Message;
}
Here's a reference in MSDN, to get up to speed.
Regarding your edit: no there is no way to access the thrown exception unless the exception is explicitly specified in your catch statement.
Yes, like this:
try
{
//Do my work!
}
catch (mySpecificException myEx)
{
//Handle my exception
}
catch (Exception ex)
{
//Handle my exception
}
(Most specific to least specific)
No.
Using the bare catch indicates that you do not care about the actual exception otherwise, why not use
catch (System.Exception ex)
to catch any exception? Of course, you should only catch exceptions you will handle.
You need to indicate the specific type of exception that you are catching, and assign that to a variable.
Do that using this syntax instead:
try
{
// Do work
}
catch (MyUndefinedExceptionObject ex)
{
Debug.WriteLine(ex.Message);
}
You can also include multiple catch blocks with the type of exception altered accordingly. However, remember that you should always order them from most derived to least derived, ending with the base class for all exceptions, System.Exception.
You also should generally refrain from catching System.Exception, instead preferring only to catch the derived exceptions that you can handle in the catch block and that won't corrupt your program's state. Catching System.Exception class is a bad idea because you'll also catch exceptions that you won't be able to handle, like an OutOfMemoryException or a StackOverflowException.
Microsoft has a helpful article on best practices here: Best Practices for Handling Exceptions
try {
}
catch (Exception) {
}
can I just write
try {
}
catch {
}
Is this ok in C# .NET 3.5? The code looks nicer, but I don't know if it's the same.
They are not the same.
catch (Exception) { } will catch managed exceptions only; catch { } will catch non-CLS exceptions as well: http://msdn.microsoft.com/en-gb/bb264489.aspx
An unhandled non-CLS compliant
exception becomes a security issue
when previously allowed permissions
are removed in the catch block.
Because non-CLS compliant exceptions
are not caught, a malicious method
that throws a non-CLS compliant
exception could run with elevated
permissions.
Edit: Turns out .NET 2.0+ wraps the values -- so they are the same. That's a bit of a relief!
Yes, the advantage of the first form is that you can name the exception variable and then use the object to log the exception details to file, etc...
try {
}
catch (Exception ex) {
// Log exception message here...
}
Also, it is generally a bad practice to catch the generic Exception class if you can instead catch specific exceptions (such as an IOException) using the first form.
Edit: As of C# 2.0, non-CLS-compliant exceptions can be caught in both ways.
So, yes. They are identical. A parameter-less catch clause without a Type declaration catches all Exceptions.
In the CLR 2.0, MS introduced RuntimeWrappedException, which is a CLS-compliant exception type, to encapsulate non-CLS-compliant exceptions. The C# compiler still doesn't allow you to throw them, but it can catch them with the catch (Exception) { } syntax.
This is why the C# compiler will issue warning CS1058 if you use both clauses at the same time on CLR 2.0 or later.
Thus, they are in fact identical.
Its the same, but if you put an e after Exception in your first example then you know what exception was thrown...
edit: you should never catch exception, how do you know how to handle it properly?
They are different as noted:
An unhandled non-CLS compliant exception becomes a security issue when previously allowed permissions are removed in the catch block. Because non-CLS compliant exceptions are not caught, a malicious method that throws a non-CLS compliant exception could run with elevated permissions.
You can see the difference in the IL generated:
//no (Exception)
.try L_0001 to L_0005 catch object handler L_0005 to L_000a
//with (Exception)
.try L_0001 to L_0005 catch [mscorlib]System.Exception handler L_0005 to L_000a
I guess unless you want to use the Exception in some sort, the second one is perfectly fine, though in order to use the exception in the first one, you need to declare a variable like this:
try {
}
catch (Exception e) {
//do something with e
}
Both of your examples appear like you're not doing anything with the exception data. This is generally not a good practice. But both are exactly the same since all exceptions classes are derived from System.Exception.
You should consider doing some type of logging then possibly rethrow the original exception or wrap it in a more specialized exception that your application can understand.
try
{
// Some code here
}
catch(Exception ex)
{
// Do some logging
throw;
}
OR
try
{
// Some code here
}
catch(Exception ex)
{
// Do some logging
// wrap your exception in some custom exception
throw new CustomException("Some custom error message, ex);
}
You should typically only catch exceptions that your code could handle, otherwise it should bubble up and it should eventually be caught by a global exception handler assuming you have one.
Parameter less constructor will cause handling of exception types coming from some other languages, exception which are not inherited from c# SYSTEM.EXCEPTION class.
what is a best practice in cases such as this one:
try
{
// do something
}
catch (SpecificException ex)
{
Response.Redirect("~/InformUserAboutAn/InternalException/");
}
the warning i get is that ex is never used.
however all i need here is to inform the user, so i don't have a need for it.
do i just do:
try
{
// do something
}
catch
{
Response.Redirect("~/InformUserAboutAn/InternalException/");
}
somehow i don't like that, seems strange!!? any tips? best practices?
what would be the way to handle this.
thnx
You just don't declare the variable:
try
{
// do something
}
catch (SpecificException)
{
Response.Redirect("~/InformUserAboutAn/InternalException/");
}
This is a moot point when catching System.Exception (in your original example, which is not exactly the same as an empty catch -- an empty catch will also catch COM exceptions, for instance), but this is the correct construct to use.
If you run your code through other analysis engines (Gendarme, for instance), you will also be warned that catching a plain Exception is poor practice because it can mask other exceptions besides what you really wanted to catch. That's bitten me a few times while maintaining legacy code -- we were catching and ignoring an Exception on a file delete (or something like that), but the main logic wasn't working correctly. We should have been only catching an IOException, but we were catching and discarding the NullReferenceException that was causing the failure.
That's not to say you never should catch Exception; just rarely.
If you don't need Exception's variable to get some information from it, don't declare it
try { }
catch ( )
is equal to
try { }
catch (Exception) { }
Use this
try { }
catch (Exception ex) { var m = ex.Message; }
if you need some information to gather.
Use this
try { }
catch (FooException) { }
catch (BarException) { }
if you need to catch only specific types of exceptions, i.e. SomeAnotherException will not be caught.
It would be better if you just let the exception bubble all the way up and use an application wide exception handler or something like ELMAH. Usually you'll want to log the exception or something so there's a record of stuff failing.
Any reason why you wouldn't let unhandled exceptions simply throw and use the Application Level error handling built into ASP.NET? See How to: Handle Application-Level Errors for more details.
I usually declare it and suffer with the warning since it can be very useful to be able to look at the exception details while debugging.
There are two reasons to declare an exception variable in a catch block. To catch only specific exception types or to do something with the exception info. In your case you are doing neither so t serves no purpose.
What are your thoughts on code that looks like this:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
throw;
}
}
The problem I see is the actual error is not handled, just throwing the exception in a different place. I find it more difficult to debug because i don't get a line number where the actual problem is.
So my question is why would this be good?
---- EDIT ----
From the answers it looks like most people are saying it's pointless to do this with no custom or specific exceptions being caught. That's what i wanted comments on, when no specific exception is being caught. I can see the point of actually doing something with a caught exception, just not the way this code is.
Depending on what quality you are looking at it is not throwing the exception in a different place. "throw" without a target rethrows the exception which is very different from throwing an exception. Primarily a rethrow does not reset the stack trace.
In this particular sample, the catch is pointless because it doesn't do anything. The exception is happily rethrown and it's almost as if the try/catch didn't exist.
I think the construction should be used for handling the exceptions you know you will be throwing inside your code; if other exception is raised, then just rethrow.
Take into account that
throw;
is different than
throw ex;
throw ex will truncate the stack to the new point of throwing, losing valuable info about the exception.
public void doSomething()
{
try
{
// actual code goes here
}
catch (EspecificException ex)
{
HandleException(ex);
}
catch (Exception ex)
{
throw;
}
}
It wouldn't be, ideally the catch block would do some handling, and then rethrow, e.g.,
try
{
//do something
}
catch (Exception ex)
{
DoSomething(ex); //handle the exception
throw;
}
Of course the re-throw will be useful if you want to do some further handling in the upper tiers of the code.
Doing something like that is fairly meaningless, and in general I try not to go down the road of doing meaningless things ;)
For the most part, I believe in catching specific types of exceptions that you know how to handle, even if that only means creating your own exception with more information and using the caught exception as the InnerException.
Sometimes this is appropriate - when you're going to handle the exception higher up in the call stack. However, you'd need to do something in that catch block other than just re-throw for it to make sense, e.g. log the error:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
LogException (ex); // Log error...
throw;
}
}
I don't think just rethrowing the error would be useful. Unless you don't really care about the error in the first place.
I think it would be better to actually do something in the catch.
You can check the MSDN Exception Handling Guide.
I've seen instances where generic exceptions are caught like this and then re-packed in a custom Exception Object.
The difference between that and what you're saying is that those custom Exception objects hold MORE information about the actual exception that happened, not less.
Well for starters I'd simply do
catch
{
throw;
}
but basically if you were trapping multiple types of exceptions you may want to handle some locally and others back up the stack.
e.g.
catch(SQLException sex) //haha
{
DoStuff(sex);
}
catch
{
throw;
}
Depends on what you mean by "looks like this", and if there is nothing else in the catch block but a rethrow... if that's the case the try catch is pointless, except, as you say, to obfuscate where the exception occurred. But if you need to do something right there, where the error occurred, but wish to handle the exception furthur up the stack, this might be appropriate. But then, the catch would be for the specific exception you are handl;ing, not for any Exception
Generally having exception handling blocks that don't do anything isn't good at all, for the simple reason that it prevents the .Net Virtual Machine from inlining your methods when performance optimising your code.
For a full article on why see "Release IS NOT Debug: 64bit Optimizations and C# Method Inlining in Release Build Call Stacks" by Scott Hanselman