Multiple-exception catches - c#

Is possible to catch more then one exception in the same catch block?
try
{ }
catch(XamlException s | ArgumentException a)
{ }

Yes. If you catch a superclass, it will also catch all subclasses too:
try
{
// Some code
}
catch(Exception e)
{
// ...
}
If this catches more than you wanted then you can rethrow the exceptions that you didn't intend to catch by testing their type. If you do this, be careful to use the throw; syntax, and not throw e;. The latter syntax clobbers the stacktrace information.
But you can't catch two different types using the syntax you propose.

Not as succinctly as you are asking. One way would be to catch all exceptions and handle those two specially:
catch(Exception e)
{
if((e is SystemException) || (e is ArgumentException))
// handle, rethrow, etc.
else
throw;
}

Not being no C# guru however, this is standard in any oop language.
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (InvalidCastException e) { out_one(e); }
catch (ArgumentNullException e) { out_two(e); }
// Least specific - anything will get caught
// here as all exceptions derive from this superclass
catch (Exception e)
{
// performance-wise, this would be better off positioned as
// a catch block of its own, calling a function (not forking an if)
if((e is SystemException) { out_two(); }
else { System..... }
}

In vb.net, it is possible to say Catch Ex As Exception When IsMyException(Ex), where IsMyException is any desired function which examines Ex and decides whether or not to catch it. The determination of whether or not to catch Ex is made before any inner Finally blocks run. Unfortunately, the makers of C# dislike the idea of allowing custom exception filters, perhaps because it would pollute the language with platform-specific details (most platforms could not support .net-style exception filters). Consequently, the best one can hope for in C# is to do something like:
void HandleThisOrThatException(BaseTypeOfThisThatTheOtherException)
{ ... }
...
// Catch ThisException or ThatException, but not TheOtherException
catch (ThisException ex) {HandleThisOrThatException(ex);}
catch (ThatException ex) {HandleThisOrThatException(ex);}

It's a bad example because any ArgumentException is also a SystemException, so catching all SystemExceptions would implicitly get the ArgumentExceptions as well.

Related

What is the recommended way to catch exceptions

I have to do a code review and i got to a code part that addresses possibles exceptions. it looks to me that the developer coding works but i want to ask what is the usual and correct way to do that. What is the best way to do catch exceptions?
the coder wrote:
try
{ . . . }
catch (Exception ex)
{
if (ex is PlatformNotSupportedException)
{ //for the Windows version or edition that does not support.
// tracing
}
else if (ex is NotSupportedException || ex is IOException)
{ // for the NTFS not supported or EFS is not configured
// tracing
}
else
{
//report any exception as encrypt/decrypt
}
}
I thought that the book says that it should be:
catch (PlatformNotSupportedException pnse)
{
//for the Windows version or edition that does not support.
// tracing
}
catch (NotSupportedException nse)
{
// for the NTFS not supported or EFS is not configured
// tracing
}
catch (IOException ioe)
{
// tracing for IOE
}
catch (Exception e)
{
//report any exception as encrypt/decrypt
}
The second approach would be more preferred. However, there is tiny difference between proposed solution and current one. You'd need to refactor to a method, or copy the code in two places (NotSupportedException and IOException catch blocks), whilst current implementation handles it under the same if block.
So, if you want to follow the same approach, you can use when keyword to filter out certain types and more.
catch (PlatformNotSupportedException pnse)
{
// for the Windows version or edition that does not support.
// tracing
}
catch (Exception ex) when (ex is NotSupportedException || ex is IOException)
{
// for the NTFS not supported or EFS is not configured
// tracing
}
catch (Exception e)
{
//report any exception as encrypt/decrypt
}
If that's not mandatory, you can leave implementation as is
TLDR: Use the second form so that the compiler catches ordering errors.
The reason that you should use the second form is because then you will get a compile error if you attempt to handle the types in the wrong order.
For example, this will give you an actual compiler error:
try
{
throw new ArgumentOutOfRangeException();
}
catch (Exception)
{
Console.WriteLine("Caught 'Exception'");
}
// This gives a compile error:
// "Error CS0160 A previous catch clause already catches all exceptions of this or of a super type ('Exception')"
catch (SystemException)
{
Console.WriteLine("Caught 'SystemException'");
}
However, using if/else if will NOT cause a compile error, so the error goes unnoticed:
try
{
throw new ArgumentOutOfRangeException();
}
catch (Exception ex)
{
if (ex is Exception)
{
Console.WriteLine("Caught 'Exception'");
}
else if (ex is SystemException) // This will never be reached, but no compile error.
{
Console.WriteLine("Caught 'SystemException'");
}
}
Note, however, that tools such as Resharper will warn you for the second case.
this would be generic for all type of exception
try
{
.....code
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

Exception handling Try-Catch block difference

I know, we can use try-catch block to handle exceptions. But I have some doubts in the usage of Try-Catch.
What is the difference between
try
{
//Some code
}
catch
{
}
and
try
{
//Some code
}
catch(Exception)
{
}
and
try
{
//Some code
}
catch(Exception oops)
{
}
In my program, I need to catch all exceptions and I don't want to log them. From the above mentioned Try-Catch blocks, which should be used?
Using a catch without a parameter is no longer useful as of framework 2.0, as all unmanaged exceptions are wrapped in a managed exception. Before that you could use it to catch exceptions thrown by unmanaged code.
You can specify just the type of the exception if you don't want to use any information from it, but usually you would want a name for it so that you can get to the information:
try {
// some code
} catch(Exception) {
// i don't care about any information in the Exception object, just the type
}
vs.
try {
// some code
} catch(Exception ex) {
// use some information from the exception:
MessageBox.Show("Internal error", ex.Message);
}
You should always try to have an exception type that is as specific as possible, as that makes it easier to handle the exception. Then you can add less specific types to handle other exceptions. Example:
try {
// some database code
} catch(SqlException ex) {
// something in the database call went wrong
} catch(Exception ex) {
// something else went wrong
}
So far you use catch (Exception), the first and the second are the same. You catch everything in this case. When you like to catch a specific exception like UnauthorizedAccessException, you have to use the second one like this:
try
{
//Some code
}
catch (UnauthorizedAccessException)
{
MessageBox.Show(oops.Message);
}
In the third case you can use the Exception through the variable oops.
For example:
try
{
//Some code
}
catch (Exception oops)
{
MessageBox.Show(oops.Message);
}
Or with a specific exception:
try
{
//Some code
}
catch (UnauthorizedAccessException oops)
{
MessageBox.Show(oops.Message);
}
Generic try catch, this will catch any type of exception
try
{
//Some code
}
catch
{
}
This will catch the specific type of exception that you specify, you can specify multiple.
try
{
}
catch (UnauthorizedAccessException)
{
}
This will do the same as above but give you a variable that has access to the properties of an exception.
try
{
}
catch (UnauthorizedAccessException ex)
{
}
You should be using the last one, and handling in a clean way your exception.
The first too way are the same but are "Eating Exceptions", witch is the worst thing to do.
At least log your exception!
Your first and second example are the same. They will both catch any exception, without any information about the exception. The third exception stores the exception in oops, which you can then use to get more information about the exception.
Look at msdn documentation: http://msdn.microsoft.com/en-us/library/vstudio/0yd65esw.aspx
The best is specify which kind of errors you would like catch.
The third one is the best...
You can catch any kind of specific exception and it will be precise... This helps in identifying the exact exception and easy for us to correct them as well
For eg: one can catch DivisionByZeroException, TargetInvocationException, ArrayOutOfBoundException, etc...
They are all pretty much the same (I assume the first is shorthand for writing the 2nd), the difference with the last is you are putting the exception object into a variable so you can use it in the catch.
Usually when I see code like this I tend to worry as it's generally not a good idea as you could be masking bigger problems with your application.
Rule of thumb - handle what you can, let everything else bubble up.
i think it has the same function - To trace where the error is set/ or where did something get wrong,
using try-catch this way
> try {
//some codes
}
catch
{
//anything
//e.g.:
MessageBox.Show("Something is wrong!");
}
this tells the that there is something wrong but didn't show the detailed report. (Clever way to hide some errors is don't put anything in the catch{} xD, but this is not advised to do)
the next is to show detailed report of the error
try
{
//some codes
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
hope this helps! :D

If exception occurs in Catch block itself then how to handle it in C#?

//I have written code in Catch Block
try {
} catch(Excepetion ex) {
// I have written code here If Exception Occurs then how to handle it.
}
You can put a try catch inside the catch block, or you can simply throw the exception again. Its better to have finally block with your try catch so that even if an exception occurs in the catch block, finally block code gets executed.
try
{
}
catch(Excepetion ex)
{
try
{
}
catch
{
}
//or simply throw;
}
finally
{
// some other mandatory task
}
Finally block may not get executed in certain exceptions. You may see Constrained Execution Regions for more reliable mechanism.
The best way is to develop your own exceptions for different Layers of application and throw it with inner exception. It will be handled at the next layer of your application. If you think, that you can get a new Exception in the catch block, just re throw this exception without handling.
Let's imagine that you have two layers: Business Logic Layer (BLL) and Data Access Layer (DAL) and in a catch block of DAL you have an exception.
DAL:
try
{
}
catch(Excepetion ex)
{
// if you don't know how should you handle this exception
// you should throw your own exception and include ex like inner exception.
throw new MyDALException(ex);
}
BLL:
try
{
// trying to use DAL
}
catch(MyDALException ex)
{
// handling
}
catch(Exception ex)
{
throw new MyBLLException(ex);
}
try
{
// Some code here
}
catch (Exception ex)
{
try
{
// Some more code
}
catch (Exception ex)
{
}
}
For the lines of code that could throw an exception in catch block make extra explicit try..ctach block. Besides consider having finally block, to have lines to run by all means there. The same question may raise for the finally block. So if your code is likely to throw some exception in the finally block, you could also add try..catch there.
try
{
}
catch (Exception ex)
{
try
{
// code that is supposed to throw an exception
}
catch (Exception ex1)
{
}
// code that is not supposed to throw an exception
}
finally
{
try
{
// code that is supposed to throw an exception
}
catch (Exception ex1)
{
}
// code that is not supposed to throw an exception
}
Double-faulting often happens in well-designed 3g programming languages. Since protected mode and the 286, the general design for hardware languages is to reset the chip on a triple fault.
You are probably ok designing your way out of a double fault. Don't feel bad about having to do something to stop processing / report an error to the user in this case. If you run into a case where, eg., you catch an IO exception (reading/writing data) and then try to close the stream you're reading from, and that also fails, its not a bad pattern to fail dramatically and warn the user that something truly exceptional happened.
A catch block isn't special in any particular way. You will have to either use another try/catch block or not handle the error.
My friend Atul.. if you if write try..catch in catch block, and if again exception occurs in inner try..catch, same problem will raise again.
So address this issue you can handle those errors in application level events in Global.asax
check below links..
http://msdn.microsoft.com/en-us/library/24395wz3%28v=vs.100%29.aspx
http://msdn.microsoft.com/en-us/library/fwzzh56s%28v=vs.80%29.aspx
let me know if this works for you.. :)

Calling methods which might throw inside catch

Let us say we have an external server which we use (e.g.-telephony station, etc.). Also we have the next code:
try
{
externalService.CreateCall(callParams);
}
catch (Exception ex)
{
_log.Error("Unexpected exception when trying execute an external code.", ex);
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
throw;
}
Theoretically UpdateCallState could throw but we would hide this exception using that code and would treat only exceptions generated by CreateCall in a right way.
The question is, what is the right pattern for these situations so that we treat all the exceptions correctly?
You can always nest another try..catch inside the first catch and deal with it appropriately.
try
{
externalService.CreateCall(callParams);
}
catch (Exception ex)
{
_log.Error("Unexpected exception when trying execute an external code.", ex);
try
{
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
}
catch(Exception updateEx)
{
// do something here, don't just swallow the exception
}
throw; // this still rethrows the original exception
}
Break it up. Something like
if !TryCreateExternalCall(callParams)
{
_log.Error("Unexpected exception when trying execute an external code.", ex);
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
}
else
{
throw new ExternalServiceException(???);
}
TryCreateExternalCall should of course log the exception and stacktrace, before it swallows and returns false.
It is not a good practice to throw exception in Catch block.
The try, Catch suggest that
try
{
//make some changes. If something goes wrong go to Catch.
}
Catch(exception)
{
//I will clean the mess. Rollback the changes.
}
Catch the exception, only if you can handle the exception. Else bubble it up let the caller decide on what to do with the exception.
You should catch the most specific exception first, followed by the most general exceptions.
try
{
externalService.CreateCall(callParams);
}
catch (CreateCallExceptionType ccEx)
{
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
}
catch (Exception ex)
{
//do something
}
And then you could handle the UpdateCallState exception within the method.

Can you catch more than one type of exception with each block? [duplicate]

This question already has answers here:
Catch multiple exceptions at once?
(29 answers)
Closed 9 years ago.
This question is close to what I want to do, but not quite there.
Is there a way to simplify the following code?
private bool ValidDirectory(string directory)
{
if (!Directory.Exists(directory))
{
if (MessageBox.Show(directory + " does not exist. Do you wish to create it?", this.Text)
== DialogResult.OK)
{
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (IOException ex)
{
lblBpsError.Text = ex.Message;
}
catch (UnauthorizedAccessException ex)
{
lblBpsError.Text = ex.Message;
}
catch (PathTooLongException ex)
{
lblBpsError.Text = ex.Message;
}
catch (DirectoryNotFoundException ex)
{
lblBpsError.Text = ex.Message;
}
catch (NotSupportedException ex)
{
lblBpsError.Text = ex.Message;
}
}
}
return false;
}
It seems a waste, and if I later want to change how I report an error back to the user, or perhaps I want to log these errors, or whatever, then I've got to change 5 different catch blocks. Am I missing something, or is this blatantly against code-reuse?
Am I just trying to be (too) lazy?
You can use :
catch (SystemException ex)
{
if( (ex is IOException)
|| (ex is UnauthorizedAccessException )
// These are redundant
// || (ex is PathTooLongException )
// || (ex is DirectoryNotFoundException )
|| (ex is NotSupportedException )
)
lblBpsError.Text = ex.Message;
else
throw;
}
If the exceptions share a common super-class then you can just catch the superclass.
Yes, you're trying to be lazy, but laziness is one of the virtues of a programmer, so that's good.
As for your question: There is no way I am aware of, but there are some workarounds available:
Give the Exceptions a common ancestor. I think this won't be possible in your case, since they seem to be builtin.
Catch the most generic exception you can.
Move the handling code into its own function and call that from each catch block.
This is annoying, and other answers have suggested good workarounds (I'd use #Lotfi's).
However this behaviour is a requirement given the type-safety of C#.
Suppose you could do this:
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (IOException,
UnauthorizedAccessException,
PathTooLongException,
DirectoryNotFoundException,
NotSupportedException ex)
{
lblBpsError.Text = ex.Message;
}
Now what type is ex? They all have .Message because they inherit System.Exception, but try accessing any of their other properties and you have a problem.
Its also important to note that when catching more then one type of exception they should be order by most specify to most general. The Exception will find the first one in the list that it matches and throw that error, none of the other errors will be thrown.
Just for completeness’ sake:
In VB, you could use conditional exception handling:
Try
…
Catch ex As Exception When TypeOf ex Is MyException OrElse _
TypeOf ex Is AnotherExecption
…
End Try
Such a Catch block would only get entered for the specified exceptions – unlike in C#.
Perhaps a future version of C# will offer a similar feature (after all, there's a specific IL instruction for that code).
MSDN: How to: Filter Errors in a Catch Block in Visual Basic
Check out the The Exception Handling Application Block from EntLib. They articulate a very nice policy and configuration based exception handling methodology that avoids large conditional logic blocks.
You can catch a base class exception (all your exceptions derive from SystemException):
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (SystemException ex)
{
lblBpsError.Text = ex.Message;
}
But then you may end up catching exceptions you don't want to catch.
You can do
ex.GetType()
see http://msdn.microsoft.com/en-us/library/system.exception.gettype.aspx
EDIT
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (Exception ex)
{ switch(ex.GetType())
case .....
case ..........
blBpsError.Text = ex.Message;
}
I understand some of these exceptions may not be foreseeable but where possible try to implement your own "pre-emptive" logic. Exceptions are expensive, though in this case probably not a deal breaker.
For example, use Directory.GetAccessControl(...) rather than relying on an UnauthorizedAccessException to be thrown.
You could use delegates, this will do what you want:
EDIT: simplified a bit
static void Main(string[] args)
{
TryCatch(() => { throw new NullReferenceException(); },
new [] { typeof(AbandonedMutexException), typeof(ArgumentException), typeof(NullReferenceException) },
ex => Console.WriteLine(ex.Message));
}
public static void TryCatch(Action action, Type[] exceptions, Action<Exception> catchBlock)
{
try
{
action();
}
catch (Exception ex)
{
if(exceptions.Any(p => ex.GetType() == p))
{
catchBlock(ex);
}
else
{
throw;
}
}
}
Your particular try/catch would be:
bool ret;
TryCatch(
() =>
{
Directory.CreateDirectory(directory);
ret = true;
},
new[]
{
typeof (IOException), typeof (UnauthorizedAccessException), typeof (PathTooLongException),
typeof (DirectoryNotFoundException), typeof (NotSupportedException)
},
ex => lblBpsError.Text = ex.Message
);
return ret;

Categories