I have seen such code in many places, is there any benefit of this..Or this is a wrong practice..
try
{
......
}
catch (NullReferenceException ex)
{
Data.LogError(ex, "Exception occourred while ...");
}
catch (IndexOutOfRangeException ex)
{
Data.LogError(ex, "Exception occourred while ...");
}
catch (Exception ex)
{
Data.LogError(ex, "Exception occourred while ...");
}
In context of specific exception handling.
There is benefit if you are going to handle the exceptions differently in the catch block (i.e. perform different actions as a result of the exception being thrown).
Otherwise you could remove the more specific exception handlers and just use the most generic:
catch(Exception ex)
Note: If the exception is being used purely for logging then sometimes it can be useful to re-throw the exception to bubble it up to the rest of the application:
try{
}
catch(Exception ex){
// Log exception here
throw;
}
This is even better than a generic catch, because you can choose what to do with a certain type of exception. Say, you want to show a message if a file doesn't exist, and offer to retry, but kill the application otherwise.
You can also handle exceptions differently, because they offer different properties (thanks to Rots for pointing that out):
try
{
}
catch(FileNotFoundException ex)
{
Console.WriteLine(ex.FileName + " not found");
//Retry
}
catch(Exception ex) // Exception does not contain ex.FileName
{
//Save stuff
//Exit
}
Only the first matching block will be executed.
The given approach is best in case if you wanted to handle/log any specific exception in it's own way. Also, ideal in scenario, where you can inform user with more apt details than giving generic messages. Now, if you don't want to handle different exceptions then you can goahead with one catch block, which catch all exception.
Related
How to detect the InvalidOperationException type
Here is the inner exception message:
System.InvalidOperationException: ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.
I need to detect exactly this type of exceptions to handle it.
Can I know its HResult number or the exception code? or another way?
This code may help
try
{
//your code here...
}
catch (Exception exception) when (exception.InnerException is InvalidOperationException)
{
var exceptionMessage = "ExecuteNonQuery requires an open and available Connection";
if (exception.Message.Contains(exceptionMessage) || exception.InnerException.Message.Contains(exceptionMessage))
{
//handle it...
}
}
You can use a try/catch exception handling hierarchy, so that InvalidOperationException will be caught first and handled separately from other exception types such as the generic exception type.
try
{
// Normal workflow up here
}
catch (System.InvalidOperationException ioex)
{
// Handle InvalidOperationException
Console.WriteLine(ioex.StackTrace);
}
catch (System.Exception ex)
{
// Handle generic exception
Console.WriteLine(ex.StackTrace);
}
However, your question suggests that this will not work for you, because you mention an inner exception. In that case you probably need to do some type checking on the inner exception like this:
try
{
// Normal workflow up here
}
catch (System.Exception ex)
{
if (ex.InnerException is InvalidOperationException)
{
// Handle InvalidOperationException
}
else
{
// Handle generic exception
}
Console.WriteLine(ex.StackTrace);
}
Could you give us more context? It would make it easier for us to answer your question.
However, if I understand you correctly, you try to process 'something' with the inner exception. As of C# 6 there are exception filters available. For more information about exception filters see Exception filters.
The documentation also provides an example.
In your specific case, you could use the exception filter as follows:
try
{
// Do something that could cause a InvalidOperationException
}
catch (InvalidOperationException ex) when (ex.InnerException is SomeTypeOfException)
{
// Handle this type of exception
}
catch (InvalidOperationException ex) when (ex.InnerException is AnotherSomeTypeOfException)
{
// Handle this kind of exception
}
I have a method for manage exception handling as below. The Question is that, in case that the typeof exception is our point, which approach is recommended? Using
catch (System.Exception ex) when(ex.GetType() ==typeof(ExcOneException)){...}
or
catch (ExcOneException ex) {...}
public T MyMethod<T>(Func<T> codeToExecute)
{
try
{
return codeToExecute.Invoke();
}
catch (System.Exception ex) when(ex.GetType() ==typeof(ExcOneException) )
{
throw new ExcOneException(ex.Message,ex);
}
catch (System.Exception ex)
{
throw new ExcTwoException(ex.Message, ex);
}
}
UPDATE: My solution has 3 projects, UI, Services and DataAccess. Each part has its own custom Exception-Handler class. Imagine that, the code in question is in service project. All codes should call this method for execution. If there is any run-time error with type of ExcOneException, it means the error is in service section, else, there should be an error in data access part; so, ExcTwoException should be thrown. This approach helps me in bubbling error up to UI level with details. What I didn't know, was that, in the case that we can use C# 6 properties, when I have filtering just on exception type, which approach is better, using catch-when or mentioning exception type as argument of catch?
Simplification & Readability:
You can filter with is, instead of typeof:
catch (Exception ex) when (ex is ExcOneException) { ... }
Chain multiple Exception types:
catch (Exception ex) when (ex is ExcOneException || ex is ExcTwoException) { ... }
Why would you ever consider that? You mention performance. Do you have any measurements that make you suspicious.
Exception filters are there for filtering exceptions that you can't catch by type, which is not your case.
In your code you are, also, not re-throwing the caught exception. You are throwing an new exception with the caught exception as an inner exception which is what you do when you want to wrap the caught exception with a more meaningful one.
If you intention is to re-throw, the correct code is:
catch (System.Exception ex)
{
throw;
}
If I wanted to catch all exceptions except for given types, and those specific types would be re-thrown to be caught in a higher context, would it be better to do:
try
{
//Code that might throw an exception
}
//Catch exceptions to be handled in this context
catch (Exception ex) when (!IsExcludedException(ex))
{
//Handle leftover exceptions
}
Or would it be better to do:
try
{
//Code that might throw an exception
}
catch (SpecificException)
{
throw;
}
//Catch exceptions to be handled in this context
catch (Exception ex)
{
//Handle leftover exceptions
}
Or does it not really matter? Is there a better way?
The second way is definitely cleaner to analyse and it's what I see the most. The specific catch happens first and doesn't trigger the generic one, but you still have a fallback if you didn't implement a specific one. Also, for handling more than one specific exception you'd need more !(ex is SpecificException) checks as well.
if I do this:
try
{
//code
}
catch (Exception)
{
throw;
}
Does the Exception go up with all its information?
The idea is to handle errors at the top of the app. There I'd execute some SQL sp to fill the admin's table so he's aware of exceptions.
I want to store Exception.Message and the source (method, function, whatever..) of the exception. But I don't know how to refer to "where" the exception happened. Is it Exception.Source? Exception.TargetSite?
Thanks.
The type of Exception will tell you what kind of exception it is (IndexOutOfRangeException, SqlException, etc) which you would react too accordingly:
try
{
//code
}
catch (SqlException ex)
{
// Handle code
}
catch (IndexOutOfRangeException ex)
{
// Handle code
}
catch (Exception ex)
{
// Handle code
}
As to where it is happening... you should be enclosing exception-prone areas with a try catch and not large code chunks. This way you will know where the exception derives from.
The Short answer is yes: just calling throw passes everthing regarding the exception up.
throw ex resets the stack trace (so your errors would appear to originate from HandleException)
throw doesn't - the original offender would be preserved.
(quoted from Mark Gravell)
Newby question...
Is it valid to do:
try
{
// code which may fail
}
catch
{
Console.Writeline("Some message");
}
Or do I always have to use:
try
{
// code which may fail
}
catch (Exception e)
{
Console.Writeline("Some message");
}
Both blocks are valid.
The first will not have an exception variable.
If you are not going to do anything with the exception variable but still want to catch specific exceptions, you can also do:
try
{
// your code here
}
catch(SpecificException)
{
// do something - perhaps you know the exception is benign
}
However, for readability I would go with the second option and use the exception variable. One of the worst things to do with exceptions is swallow them silently - at the minimum, log the exception.
Yep, absolutely, such a catch block called general catch clause, see more interesting details in the C# Language Specification 4.0, 8.10 The try statement:
A catch clause that specifies neither an exception type nor an
exception variable name is called a general catch clause. A try
statement can only have one general catch clause, and if one is
present it must be the last catch clause
Yes, your first block of code valid. It will catch all exceptions.
It is. It will catch all the exception. So the two code examples do the same.
First one is valid, and it acts just like the second one.
http://msdn.microsoft.com/en-us/library/0yd65esw%28v=vs.80%29.aspx
The catch clause can be used without arguments, in which case it
catches any type of exception, and referred to as the general catch
clause. It can also take an object argument derived from
System.Exception, in which case it handles a specific exception.
Yes it is valid.
you can always refer to this article:
Best Practices for Handling Exceptions on MSDN
Of course it is valid, you specify catch(Exception e) when you want to output the error message ex.Message, or to catch a custom or a concrete Exception. Use catch in your situation.
As #David answered this is valid.
You could use second syntax if you want to get more infos or catch a specific exception.
E.g.
catch (Exception e)
{
Debug.Print(e.Message);
}
catch (Exception e)
{
Console.Writeline("Some message");
}
In this block you can use SqlException, etc..
catch (SqlException e)
{
Console.Writeline("Some message");
}
For this use the "(SqlException e)"
If you will use a generic menssage, use this:
catch
{
Console.Writeline("Some message");
}
or
catch (Exception)
{
Console.Writeline("Some message");
}
Don't forget that you can chain catch your exceptions. This will allow you to handle different scenarios based upon the exception(s) the code may throw.
try
{
//Your code.
}
catch(SpecificException specificException)
{
//Handle the SpecificException
}
catch(AnotherSpecificException anotherSpecificException)
{
//Handle AnotherSpecificException
}
catch(Exception exception)
{
//Handle any Exception
}