.NET exception caught is unexpectedly null - c#

See below for an explanation of what is going on
I have a really weird issue where the exception caught is null.
The code uses MEF and tries hard to report composition errors. Using the debugger I can see the exception being thrown (an InvalidOperationException) but when it is caught by the last catch block in the code below the ex variable is null. This is true both in the debugger and when executing the code normally.
static T ResolveWithErrorHandling<T>() where T : class
{
try
{
IocContainer.Compose(Settings.Default.IocConfiguration);
return IocContainer.Resolve<T>();
}
catch (ReflectionTypeLoadException ex)
{
// ... special error reporting for ReflectionTypeLoadException
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ... general error reporting for other exception types
}
return null;
}
The code I have replaced with comments is really simple code to format the error message. Nothing strange going on there.
I have tried to alter the code to discover what effect that might have:
If I remove the first catch block (ReflectionTypeLoadException) the exception caught in the final catch block is no longer null.
If I catch another exception type in the first catch block the exception caught in the final catch block is no longer null.
If I add a catch block for InvalidOperationException as the first catch block the exception caught in that block is not null.
If I add a catch block for InvalidOperationException between the two catch blocks the exception caught in that block is null.
The project uses Code Contracts and the code generated by the compiler is post-processed to check the contracts. Unfortunately, I havn't figured out a way to get rid of this for testing purposes without performing major surgery on the project.
My current workaround is to not catch ReflectionTypeLoadException and instead branch on the type of ex in the general exception handler.
What could be the explanation for this "impossible" behavior? What is up with ReflectionTypeLoadException catch block?
Embarrassingly the exception is not null and it cannot be null per the C# standard 15.9.5.
However, using Code Contracts in a project can mess up the display of local variables in the debugger because the IL code generated by the compiler can be rewritten by Code Contracts so the final IL is slightly out of sync with the debug information. In my case the ex variable is displayed as null even it is not. The unfortunate nature of the error reporting taking place right before application termination meant that I believed the error reporting to not be called as a result of ex being null and ex.Message throwing a NullReferenceException inside my catch block. Using the debugger I was able to "verify" that ex was null, except it was actually not null.
My confusion was compounded by the fact that a catch block for ReflectionTypeLoadException seems to affect the debugger display issue.
Thanks to all who responded.

Just ran into this same problem. I finally found out that I catched different exceptions with the same name, like you did:
catch (ReflectionTypeLoadException ex)
{
// ...
}
catch (Exception ex)
{
// ex is not null!
// ...
}
Both are named 'ex'. Changing one of both names solved this problem for me, like:
catch (ReflectionTypeLoadException reflectionEx)
{
// ...
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ...
}

I ran in the same problem. In my case renaming the exception variable (e.g. ex => ex1) allowed to me to catch any exception...

You should check if at some point, the IocContainer catches an Exception ex throws ex.InnerException without checking if it is null.
C# happily accepts throw null, and ends up in catch (Exception).

I ran into the same problem. The exception was null when viewed in the debugger even though the correct type of exception - UpdateException - was being caught. I could view the exception by opening the Exception Assistant.
As soon as I turned off "Perform Runtime Contract Checking" caught exceptions where no longer null. I have been actively using code contracts for going on a year now and had not seen this problem before I starting working with EF 4.1 in this particular project recently - but I do not know if EF was a controlling variable in regards to caught exceptions being null.

The exception is in fact not null, it's a problem with the debugger.
Code contracts (ccrewrite) changes IL opcodes and that perturbates the debugger, because leave.s opcodes are transformed into leave opcodes.
The two opcodes have different sizes and instruction adresses change, that's why the debugger is lost when exception names are the same.
You can use $exception in the debugger to workaround the issue.

I have got the same situation, too. It happened to be a bug of Eclipse debugger. (Really, this situation can be only the result of some debugger's bug. )
Eclipse restart was enough - runtime exception becomes normal, not null. Other debuggers could be not so kind.

Related

C# catch(FileNotFoundException) and CA1031

So this code triggers CA1031.
try
{
// logic
}
catch (FileNotFoundException) // exception type
{
// handle error
}
While this one does not:
try
{
// logic
}
catch (FileNotFoundException ex) // exception var
{
// handle error
}
Because the exception type is meaningful, I don't need the ex in the first example. But it's not a a general exception type. It's not IOException or Exception. So why does it still trigger the CA1031?
So is there a difference between catch(FileNotFoundException) and catch(FileNotFoundException ex) outside the fact that I don't capture exception info?
So this code triggers CA1031
try
{
// logic
}
catch (FileNotFoundException) // exception type
{
// handle error
}
This occurs because a "general exception such as System.Exception or System.SystemException is caught in a catch statement, or a general catch clause such as catch() is used". To fix it, assign it and handle the error and or rethrow the general exception for it to be handled further up.
Upon further investigation, it seems this used to be an bug, you can see more here; it was a Roslyn issue for FxCop.
To Fix:
Just update the latest FxCop analyzers package and it should go way.
NuGet:
Install-Package Microsoft.CodeAnalysis.FxCopAnalyzers -Version 2.9.7
References:
CA1031
I have two Articles I use as basis for my Exception handling:
https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET
I also link those often when I notice Exception handling errors.
FileNotFound is clearly a exogenous Exception, so it is correct to catch it. However those articles also tell that as a general rule, to always log or expose those Exceptions. Ideally the result of Exception.ToString(). If you do not have a way to reference the caught exception, how could you do either of those two? You can only give a generic error message, but with none of the details you will actually need to debug it.
While there are many cases where you only want to expose the Exception type to the user, there is never one where you only want to log the Exception type. The linked articles mention that explicitly, but due to downvotes and comments it seems nessesary for me to repeat that.
So it is one of those cases where the argument is still going if it is a bug or a feature.
For me it certainly feels more like a feature. I would certainly call you out as potentiall issue, if I saw it in your code. It avoids you under-logging stuff. You could test if the error persist if you write throw; at the end of the catch block. This will re-throw on the exception, so a lack of being able to reference the exception in this ExceptionHandler would not be critical.

Are these try/catch'es equivalent?

Scenario
I have a method that does database operation (let's say). If during that operation any exception is raised, I just want to throw that exception to the caller. I don't want to do any specific task in the catch block, assuming caller will do whatever it wants to do with that exception. In this scenario, which one is appropriate exception handling technique?
try
{
// Some work that may generate exception
}
catch(Exception)
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/catch/finally?
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/finally?
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
Which one is better than the other? Which one should be used?
No, they are not equivalent. They may be equivalent in some cases, but the general answer is no.
Different kinds of catch blocks
catch block with a specified exception type
The following will only catch managed exceptions that inherit from System.Exception and then executes the finally block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch (Exception)
{
throw;
}
finally
{
// Some final work
}
catch block without a specified exception type
The following catch block without a type specifier will also catch non-managed exceptions that are not necessarily represented by a managed System.Exception object, and then executes the finally block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
finally block without a catch block
If you do not have a catch block at all, your finally will still be executed regardless of whether or not an exception occoured.
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
When are they equivalent?
In case your catch block doesn't specify an exception and only contains the throw; statement, the last two are indeed equivalent. In case you don't care about non-managed exceptions and your catch block only contains the throw; statement, all three can be considered equivalent.
Notes
A note about throw
The following two pieces of code contain a subtle difference. The latter will re-throw the exception, meaning that it will rewrite the exception's stack trace, so these are definitely not equivalent:
catch (Exception e)
{
throw;
}
And
catch (Exception e)
{
throw e;
}
In case you use finally with an IDisposable, the following two pieces of code are almost equivalent, but with some subtle differences:
When the object is null, the using statement won't give you a NullReferenceException
When using the try-finally technique, the variable remains in scope, although it is very discouraged to use any object after it has been disposed. However you can still reassign the variable to something else.
Something obj = null;
try
{
obj = new Something()
// Do something
}
finally
{
obj.Dispose();
}
And
using (var obj = new Something())
{
// Do something
}
You have some good answers so far, but there is an interesting difference that they did not mention so far. Consider:
try { ImpersonateAdmin(); DoWork(); }
finally { RevertImpersonation(); }
vs
try { ImpersonateAdmin(); DoWork(); }
catch { RevertImpersonation(); throw; }
finally { RevertImpersonation(); }
Suppose DoWork throws.
Now the first question at hand is "is there a catch block that can handle this exception", because if the answer is "no" then the behaviour of the program is implementation-defined. The runtime might choose to terminate the process immediately, it might choose to run the finally blocks before it terminates the process, it might choose to start a debugger broken at the point of the unhandled exception, it might choose to do anything it likes. Programs with unhandled exceptions are permitted to do anything.
So the runtime starts looking for a catch block. There's none in this try statement, so it looks up the call stack. Suppose it finds one with an exception filter. It needs to know if the filter will permit the exception to be handled, so the filter runs before impersonation is reverted. If the filter accidentally or deliberately does something that only an admin can do, it will succeed! This might not be what you want.
In the second example, the catch catches the exception immediately, reverts the impersonation, throws, and now the runtime starts looking for a catch block to handle the re-throw. Now if there is a filter it runs after the impersonation is reverted. (And of course the finally then reverts again; I assume that reverting impersonation is idempotent here.)
This is an important difference between these two code snippets. If it is absolutely positively forbidden for any code to see the global state that was messed up by the try and cleaned up by the finally, then you have to catch before finally. "Finally" does not mean "immediately", it means "eventually".
Both of the try / catch statements are equivalent in that they are re-throwing the original exception that was caught. However the empty catch is more broad (as Venemo has already stated, catching unmanaged exceptions). If you are to catch an exception and capture it in a variable you can use it for logging or you can throw a new exception while passing the original exception as an argument - making it the "inner exception".
The finally is going to function the same regardless.
Which one should be used, in a scenario where we don't need logging exception and we explicitly assume caller will handle exception being raised like writing in file stream or sending email.
If the caller will handle the exception and you do not need to log the occurrence of the exception at this level, then you should not be catching at all. If the caller will handle an exception being thrown, there is no need to catch an exception just to re-throw it.
Valid reasons to catch an exception that will be re-thrown:
throw new Exception("WTF Happened", ex); // Use as inner exception
Log exception
Use a finally block to execute some cleanup code

Try catch and re-throw exception

I saw some code the other day in one of our projects that uses a try catch and re-throws the caught exception like this:
try
{
exceptionProneCode();
}
catch(Exception ex)
{
throw ex;
}
Nothing else was done with the exception in the catch block so I'm not even sure why it's re-thrown. I can't see any benefit to actually throwing the same exception again and doing nothing with the exception.
If you re-throw an exception that's caught in the catch block, how does C# handle this? Does it get stuck in an infinite throw/catch loop? Or does it eventually leave the try catch?
Consider these two models:
1- By re-throwing ex:
catch(Exception ex)
{
throw ex;
}
you loose StackTrace. If the exception is logged somewhere the StackTrace containing immediate frames of the call stack (history of method calls) is lost.
2- In contrast by throw:
catch(Exception ex)
{
// do something here
throw;
}
you maintain StackTrace. You can do additional processing and then re-throw the exception without loosing the trace string.
It continues to throw the exception up the calls stack. One thing that this piece of code does that is different from if you didn't catch the exception, it will reset the exception location (call stacks, line #, etc) to where you re-threw the exception, so you won't have the location where the original exception was thrown.
If you're not going to actually do something in the catch block I would recommend not catching, or at the very least rethrowing with just a throw instead of throw ex.
It throws the exception to the caller. But it handles it here so it doesn't throw an unhandled exception. However, honestly, I don't see the benefit of this. Just let it throw the exception. Why? Because an exception is only unhandled if the entire call stack above it doesn't have a try ... catch. This isn't doing anything useful.
Does it get stuck in an infinite throw/catch
loop? Or does it eventually leave the try catch?
No. Yes.
The code provides no benefit and does harm to debugging as noted by everyone else.
A good catch block will catch a specific expected issue and log & continue (the problem doesn't indicate the applications state is corrupt), log and halt (because the application is now in an unknown state and continuing could wreck more harm), do something else (e.g. fall back to an equivalent technology/algorithm), wait and try again.
The default is that something is unexpected, should be logged and the application should be stopped-- either abandoning the page or if a winforms app, revert back to a known state if possible.

Try/Catch block not catching Exception

I have a statement inside a try/catch block, but the exception is not getting caught. Can anyone explain?
Exception Details:
System.NullReferenceException: Object
reference not set to an instance of an
object.
Source Error:
Line 139: try
Line 140: {
Line 141: return (int)Session["SelectedLeadID"];
Line 142: }
Line 143: catch (Exception ex)
Update
This is an ASP.NET application. In the catch block, a new exception is thrown. The code you see is what is displayed on the ASP.NET error page.
That catch block should catch the exception, but make sure there's no re-throwing in there.
Another small comment: I've been tricked quite a few times by VS, cause it breaks on exceptions like that while running in debug-mode. Try to simply press 'continue' or 'F5' and see if your application doesn't work anyway :)
I suspect you're going to need to add more detail - that isn't reproducible just from your code. In particular (as already noted) we'd need to see inside the catch, and verify that the exception is actually being thrown from inside the try and not somewhere else.
Other possibilities:
you have dodgy code inside the exception handler that is itself throwing an exception
you have a dodgy Dispose() that is getting called (using etc)
you are in .NET 1.1 and the thing getting thrown (in code not shown) isn't an Exception, but some other object
If it is only the debugger breaking on the exception and you are using VS2005 or above, you might want to check under Debug->Exceptions... if any of the Common-Language-Runtime-Exceptions are activated. If so, the debugger will always catch the exceptions first, but you are allowed to continue.
To revert to normal execution, simply uncheck the apropriate exceptions from the list.
I also faced this problem
Image
which was solved by removing the tick of
"Break when this exception type is thrown."
Warning:
Of course, I am not aware of the consequences of this.
I've also had such an issue and it was driving me nuts for quite some time, but in the end I figured it out. It's quite stupid, but maybe it might help someone:
public IActionResult SomeFunction()
{
try
{
return Json(new ClassWhichTakes2Parameters("FirstParameter"), "SecondParameter"); //comma placed in the wrong spot
}
catch (Exception ex)
{
//some code
}
}
It should have looked like:
public IActionResult SomeFunction()
{
try
{
return Json(new ClassWhichTakes2Parameters("FirstParameter", "SecondParameter"));
}
catch (Exception ex)
{
//some code
}
}
Since I had many return statements in that function I didn't catch this right away.
Also, the error message I've been receiving wasn't quite what I have expected at first, but now it makes sense:
System.InvalidOperationException: Property
'JsonResult.SerializerSettings' must be an instance of type
'Newtonsoft.Json.JsonSerializerSettings'.
The code looks terribly ugly IMO. For there to be something in the catch() block means you are going to have another return ... statement which AFAIK you should always have a single return statement at the end of each function to make following code easier.
i.e. maybe your code should look like
public int Function()
{
int leadID = 0;
try
{
int leadID = (int)Session["SelectedLeadID"];
}
catch (Exception ex)
{
...
}
return leadID
}
Single exit points are supposed to make the code easier to follow, I guess? Anyway, to get any useful help you have to post more of the function.

Is this a bad practice to catch a non-specific exception such as System.Exception? Why?

I am currently doing a code review and the following code made me jump. I see multiple issues with this code. Do you agree with me? If so, how do I explain to my colleague that this is wrong (stubborn type...)?
Catch a generic exception (Exception ex)
The use of "if (ex is something)" instead of having another catch block
We eat SoapException, HttpException and WebException. But if the Web Service failed, there not much to do.
Code:
try
{
// Call to a WebService
}
catch (Exception ex)
{
if (ex is SoapException || ex is HttpException || ex is WebException)
{
// Log Error and eat it.
}
else
{
throw;
}
}
The mantra is:
You should only catch exceptions if
you can properly handle them
Thus:
You should not catch general
exceptions.
In your case, yes, you should just catch those exceptions and do something helpful (probably not just eat them--you could throw after you log them).
Your coder is using throw (not throw ex) which is good.
This is how you can catch multiple, specific exceptions:
try
{
// Call to a WebService
}
catch (SoapException ex)
{
// Log Error and eat it
}
catch (HttpException ex)
{
// Log Error and eat it
}
catch (WebException ex)
{
// Log Error and eat it
}
This is pretty much equivalent to what your code does. Your dev probably did it that way to avoid duplicating the "log error and eat it" blocks.
I am currently doing a code review and the following code made me jump. I see multiple issues with this code. Do you agree with me?
Not totally, see below.
Catch a generic exception (Exception ex)
In general, catching a generic exception is actually ok as long as you rethrow it (with throw;) when you come to the conclusion that you can't handle it. The code does that, so no immediate problem here.
The use of "if (ex is something)" instead of having another catch block
The net effect of the catch block is that only SoapException, HttpException, etc. are actually handled and all other exceptions are propagated up the call stack. I guess functionality-wise this is what the code is supposed to do, so there's no problem here either.
However, from a aesthetics & readability POV I would prefer multiple catch blocks to the "if (ex is SoapException || ..)". Once you refactor the common handling code into a method, the multiple catch blocks are only slightly more typing and are easier to read for most developers. Also, the final throw is easily overlooked.
We eat SoapException, HttpException and WebException. But if the Web Service failed, there not much to do.
Here possibly lurks the biggest problem of the code, but it's hard to give advice without knowing more about the nature of the application. If the web service call is doing something that you depend on later then it's probably wrong to just log & eat the exceptions. Typically, you let the exception propagate to the caller (usually after wrapping it into e.g. a XyzWebServiceDownException), maybe even after retrying the webservice call a few times (to be more robust when there are spurious network issues).
The problem with catching and re-throwing the same exception is that, although .NET does its best to keep the stack trace intact, it always ends up getting modified which can make tracking down where the exception actually came from more difficult (e.g. the exception line number will likely appear to be the line of the re-throw statement rather than the line where the exception was originally raised). There's a whole load more information about the difference between catch/rethrow, filtering, and not catching here.
When there is duplicate logic like this, what you really need is an exception filter so you only catch the exception types you're interested in. VB.NET has this functionality, but unfortunately C# doesn't. A hypothetical syntax might look like:
try
{
// Call to a WebService
}
catch (Exception ex) if (ex is SoapException || ex is HttpException || /* etc. */)
{
// Log Error and eat it
}
As you can't do this though, what I tend to do instead is use a lambda expression for the common code (you could use a delegate in C# 2.0), e.g.
Action<Exception> logAndEat = ex =>
{
// Log Error and eat it
};
try
{
// Call to a WebService
}
catch (SoapException ex)
{
logAndEat(ex);
}
catch (HttpException ex)
{
logAndEat(ex);
}
catch (WebException ex)
{
logAndEat(ex);
}
I would like to add here, because the Exception handling in almost all java / C# code that I have seen is just incorrect. I.e. you end up with very difficult to debug error for ignored Exceptions, or, equally bad, you get an obscure exception which tells you nothing, because blindly following the "catching(Exception) is bad" and things are just worse.
First, understand that an exception is a way to facilitate the returning of error information across code layers. Now, mistake 1: a layer is not just a stack frame, a layer is code which has a well defined responsibility. If you just coded interfaces and impls just because, well you have better things to fix.
If the layers are well designed and have specific responsibilities, then the information of the error has different meaning as it bubbles up. <-this is the key on what to do, there is no universal rule.
So, this means that when an Exception occurs you have 2 options, but you need to understand where in the layer you are:
A) If you are in the middle of a layer, and you are just an internal, normally private, helper function and something goes bad: DONT WORRY, let the caller receive the exception. Its perfectly OK because you have no business context and
1) You are not ignoring the error and
2) The caller is part of your layer and should have known this can happen, but you might not now the context to handle it down below.
or ...
B) You are the top boundary of the layer, the facade to the internals. Then if you get an exception the default shall be to CATCH ALL and stop any specific exceptions from crossing to the upper layer which will make no sense to the caller, or even worse, you might change and the caller will have a dependency to an implementation detail and both will break.
The strength of an application is the decoupling level between the layers. Here you will stop everything as a general rule and rethrow the error with a generic exception translating the information to a more meaningful error for the upper layer.
RULE: All entry points to a layer shall be protected with CATCH ALL and all errors translated or handled. Now this 'handeled' happens only 1% of the time, mostly you just need (or can) return the error in a correct abstraction.
No I am sure this is very difficult to understand. real Example ->
I have a package that runs some simulations. These simulations are in text scripts. there is a package that compiles these scripts and there is a generic utils package that just reads text files and, of course, the base java RTL. The UML dependency is->
Simulator->Compiler->utilsTextLoader->Java File
1) If something breaks in the utils loader inside one private and I get a FileNotFound, Permissions or what ever, well just let it pass. There is nothing else you can do.
2) At the boundary, in the utilsTextLoader function initially called you will follow the above rule and CATCH_ALL. The compiler does not care on what happen, it just needs to now whether the file was loaded or not. So in the catch, re throw a new exception and translate the FileNotFound or whatever to "Could not read file XXXX".
3) The compiler will now know that the source was not loaded. Thats ALL it needs to know. So if I later I change utilsTestLoader to load from network the compiler will not change. If you let go FileNotFound and later change you will impact compiler for nothing.
4) The cycle repeats: The actual function that called the lower layer for the file will do nothing upon getting the exception. So it lets it go up.
5) As the exception gets to the layer between simulator and compiler the compiler again CATCHES_ALL, hiding any detail and just throws a more specific error: "Could not compile script XXX"
6) Finally repeat the cycle one more time, the simulator function that called the compiler just lets go.
7) The finally boundary is to the user. The user is a LAYER and all applies. The main has a try that catches_ALL and finally just makes a nice dialog box or page and "throws" a translated error to the user.
So the user sees.
Simulator: Fatal error could not start simulator
-Compiler: Could not compile script FOO1
--TextLoader: Could not read file foo1.scp
---trl: FileNotFound
Compare to:
a) Compiler: NullPointer Exception <-common case and a lost night debugging a file name typo
b) Loader: File not found <- Did I mention that loader loads hundreds of scripts ??
or
c) Nothing happens because all was ignored!!!
Of course this assumes that on every rethrow you didn't forget to set the cause exception.
Well my 2cts. This simple rules have saved my life many times...
-Ale
Sometimes that is to only way to handle "catch every exception" scenarios, without actually catching every exception.
I think sometimes, say, lowlevel framework / runtime code needs to make sure that no exception is ever escaping. Unfortunately, there is also no way the framework code can know which exceptions are raised by the code executed by the thread.
In that case a possible catch block could look like this:
try
{
// User code called here
}
catch (Exception ex)
{
if (ExceptionIsFatal(ex))
throw;
Log(ex);
}
There are three important points here, however:
This isn't something for every situation. In code reviews we are very picky about places where this is actually neccessary and thus allowed.
The ExceptionIsFatal() method assures that we don't eat exceptions which should never be swallowed (ExecutionEngineException, OutOfMemoryException, ThreadAbortException, etc.)
What is swallowed is carefully logged (event-log, log4net, YMMV)
Typically, I'm all for the practice of letting uncaught exceptions simply "crash" the application by terminating the CLR. However, especially in server applications, this is sometimes not sensible. If one thread encounters a problem which is deemed non-fatal, there is no reason in ripping the whole process down, killing off all other running requests (WCF, for example, handles some cases this way).
You should usually still catch generic exceptions in a global handler (which is the perfect place to log unexpected Exceptions), but otherwise as said before, you should only catch specific exception types in other places if you plan to do something with them. The catch blocks should look for those exception types explicitly, not as the code you posted does.
I don't think this is such a bad thing in this case, but I also do something similar in my code with exceptions that can be safely ignored being caught and the rest being re-thrown. As noted by Michael's response, having each catch being a separate block could cause some readability issues which are prevented by going this route.
In regards to pointing this out to your colleague, I think you would have a hard time convincing them that this is the wrong way of doing things - even more so if they are stubborn - because of the potential readability issues with doing things the other way. Since this version is still throwing the generic exception's that can't be handled it is in keeping with the spirit of the practice. However, if the code was in line with the following:
try
{
// Do some work
}
catch (Exception ex)
{
if (ex is SoapException)
{
// SoapException specific recovery actions
}
else if (ex is HttpException)
{
// HttpException specific recovery actions
}
else if (ex is WebException)
{
// WebException specific recoery actions
}
else
{
throw;
}
}
Then I think you would have a bit more of a reason to be concerned as there is no point in doing work for a specific exception by checking for it in a general exception block.
the princeple is only to catch the exception you can handle.
such as, if you know how to deal with findnotfound, you catch the filenotfoundexception, otherwiese, do NOT catch it and let it be thrown to the upper layer.

Categories