Reputation: 86
I believe I'm following the correct process to implement a custom exception, but the exception arrives in the catch block wrapped in a System.Exception, so the handling for my custom exception doesn't execute.
I create the custom exception class (following examples found online):
using System;
using System.Runtime.Serialization;
namespace La.Di.Da
{
[Serializable]
public class MyCustomException : Exception
{
public MyCustomException()
: base()
{
}
public MyCustomException(string message)
: base(message)
{
}
...
}
I throw the exception, from a lower point in the stack:
...
if (up == down)
{
throw new MyCustomException("Things are topsy-turvy.");
}
...
The exception is caught at an intermediate try-catch. I know such catching-logging-throwing is wrong practice but this code is in an existing method that's called a lot in this application, and regression testing the entire application for my small change isn't an option. Anyway, this catch-throw isn't causing the problem: The exception arrives in this catch already as a System.Exception wrapping my custom exception.
try
{
DoSomeStuff(();
}
catch (Exception ex)
{
LogManager.Instance.LogException(ex);
throw;
}
finally
{
DoSomeCleanup();
}
I have code to catch the custom exception at the next catch up the stack. But the exception arrives as a System.Exception wrapping the custom exception, so my custom exception handling doesn't get executed.
...
try
{
CallAMethod();
}
catch MyCustomException(ex)
{
LogManager.Instance.LogException(ex);
ShowErrorMessage(ex.Message);
}
catch Exception(ex)
{
throw ex;
}
I believe the exception I'm throwing shouldn't be wrapped, so I must be doing something wrong. Any suggestions?
Upvotes: 1
Views: 1517
Reputation: 52240
An exception handler will catch any exception that is or is derived from the specified exception type.
For example
catch (System.Exception e)
{
//Handler
}
...will catch everything. Meanwhile
catch (System.ApplicationException e)
{
//Handler
}
...will catch all exceptions that derive from ApplicationException. This includes all of these:
Microsoft.JScript.NoContextException, Microsoft.JScript.ReturnOutOfFinally, System.Reflection.InvalidFilterCriteriaException, System.Reflection.TargetException, System.Reflection.TargetInvocationException, System.Reflection.TargetParameterCountException, System.Threading.WaitHandleCannotBeOpenedException
This is exactly why you should never catch System.Exception
. It catches everything!
This is also why exception handlers are declared in order from specific to general-- if the general handler were first, none of the other handlers would ever fire.
Get rid of the catch (System.Exception)
if you can.
If you can't get rid of your catch (System.Exception)
block, you can use a when filter so that it will ignore your custom exception, like this:
catch (System.Exception e) when (!(e is MyCustomException))
{
//Handler
}
Upvotes: 1
Reputation: 2205
Not an answer to your query, but generally, your Custom exception should include these 3 constructors (may be you already have it)
Use at least the three common constructors when creating your own exception classes: the default constructor, a constructor that takes a string message, and a constructor that takes a string message and an inner exception.
This will allow you to chain exceptions, i.e., the InnerException
property can contain another exception object, whose InnerException
can contain another one, and so on.
Also, your handler which has just the throw
statement is the correct way (in most cases), as it would preserve the stack trace info.
Upvotes: 0
Reputation: 3551
public class MyCustomException : Exception
That code means your class is extending the Exception
class. So when you throw it, and catch it with an Exception
catch, it is held as that base class. You can always cast it back to MyCustomException
.
If by wrapping, you mean that your custom exception is included as an inner exception, it's likely because of your re-throwing the exception.
It also may be how your second set of try catches function. I haven't seen that style before so it may be valid, but try it written as
catch(MyCustomException ex){
...
}
instead
Upvotes: 1