it is allowed to use custom exception, where the exception can be thrown like below.
try
{
int foo = int.Parse(token);
}
catch (FormatException ex)
{
//Assuming you added this constructor
throw new ParserException(
$"Failed to read {token} as number.",
FileName,
LineNumber,
ex);
}
But in a normal try catch block, it says , throwing exceptions will clear the stacktrace.
try
{
ForthCall();
}
catch (Exception ex)
{
throw ex;
}
So in custom exception,how it managed to use throw exception, without clear the stacktrace?
There are several ways this can be done.
As mentioned in this link In C#, how can I rethrow InnerException without losing stack trace?, you can use the ExceptionDispatchInfo Class
with code similar to
try
{
task.Wait();
}
catch(AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
Another way is to have your handler return a boolean, whether the exception was handled or not, so you can use this in your catch clause:
catch (Exception ex) {
if (!HandleException(ex)) {
throw;
}
}
where HandleException is your custom Exception handler. Gotten from this link: How to throw exception without resetting stack trace?
Whenever you use throw with an exception object, it fills in the stack trace at that point. (Compare to Java, which populates stack traces when an exception is constructed.)
If you use throw without an exception object, which you can only do in a catch clause, the caught exception object is re-throw without alteration.
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;
}
static void Main(string[] args)
{
try
{
var intValue = "test";
var test = Convert.ToInt32(intValue);
}
catch (FormatException)
{
Console.WriteLine("format exception");
throw;
}
catch (Exception)
{
}
finally
{
Console.WriteLine("finally");
}
}
According to me, during conversion from string to int, a FormatException is thrown. Now inside the catch block, we are re throwing the original exception. Why is this not caught in the generic exception catch block? If I put try/catch around the throw then application doesn't crashes.
Why is this not caught in the generic exception catch block?
Because the generic exception block catches exceptions that are thrown only within the try block and doesn't catch exceptions thrown from catch blocks.
So if you intend to throw an exception from the catch block and you want to handle it, you will need to wrap the calling code in yet another try/catch.
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)
I have an aspx page that, on a button click, creates an instance of a serviceRefernece object. In the code behind for my page I have the call wrapped in a try/catch.
try
{
var client = GetClient();
var request = new ActiveVerificationRequestDC();
var response = client.GetActiveVerification(request);
DoSomethingWithTheResponse(response);
}
catch (FaultException ex)
{
LogError(ex, MethodBase.GetCurrentMethod().Name);
throw;
}
catch (Exception ex)
{
var args = new[] { MethodBase.GetCurrentMethod().Name, ex.Message };
DisplayError(args);
}
The svc file that is referenced is using pretty much the same pattern. It is calling an internal client over net.tcp. The call is wrapped in a try/catch
try
{
var client = new InternalServiceClient();
var response = client.GetActiveVerification(request);
client.Close();
return response;
}
catch (FaultException fe)
{
LogError(MethodBase.GetCurrentMethod().Name, fe);
throw;
}
Here is my problem, how do I get errors here to bubble up to my UI catch statement? When I leave it like this, I get an unhandled exception error from visual studio. I have tried removing the throw which makes me specify a return value, and I return null. This makes the UI not work correctly. I have tried throw new Exception(fe.message) and I get the same problem with the unhandled exception. Basically my question is how can I accomplish what I need? What am I missing?
You need a separate try/catch block around your try/catch block. You have it such that you will catch a FaultException and any type of Exception, but your Exception block will not catch your throw from FaultException. So, just enclose this with another try/catch or handle it within both the FaultException catch and the Exception catch.
The reason could be the throwing of another exception in your second code snippet that isn't of the type FaultException; such an exception would pass as unhandled in this situation. Maybe you should add another catch block to your second code snippet that catches exceptions of the type Exception:
catch (FaultException fe)
{
LogError(MethodBase.GetCurrentMethod().Name, fe);
throw;
}
catch (Exception ex)
{
throw;
}
Is the FaultException you are re-throwing a generic type? Are the relevant classes detailed by any FaultContract attributes accessible to all assemblies in this execution stack?
Edit: In your first code snippet ...
catch (FaultException ex)
{
LogError(ex, MethodBase.GetCurrentMethod().Name);
throw;
}
If the unhandled error occurs on the throw statement of this handler, then #MCain is right.
I believe you have to throw in the catch block for the error to bubble up
try
{
}
catch (SqlException _SqlException)
{
//Log Error to file
throw;
}
catch (IOException _IOexception)
{
//Log Error to file
throw;
}
catch (Exception _exception)
{
//Log Error to file
throw;
}
This kind of a block will be in the calling method