Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where/how to store or handle a lot of custom exceptions?

Tags:

c#

.net

exception

Lets say I would like to make some custom exceptions. And I would like to have more of them. I could create for every new exception a new class, but is there another way to do this? And if I have to create always a new class, where to store them? Its just looking not that nice in the root folder of a project.

Ahm and another question: what am I doing if some exceptions are the same, just the name of the exception is changing a little bit? Lets say exception A is looking like this:

    [Serializable()]
    public class ExceptionA: Exception, ISerializable
    {
        public ExceptionA() : base() { }
        public ExceptionA(string message) : base(message) { }
        public ExceptionA(string message, System.Exception inner) : base(message, inner) { }
        public ExceptionA(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}

and another one is the same, just another name:

    [Serializable()]
    public class ExceptionB: Exception, ISerializable
    {
        public ExceptionB() : base() { }
        public ExceptionB(string message) : base(message) { }
        public ExceptionB(string message, System.Exception inner) : base(message, inner) { }
        public ExceptionB(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}

And so on. Do I really have to create always a new class and paste the same code? Any suggestions?

like image 299
silla Avatar asked Sep 06 '12 10:09

silla


3 Answers

I could create for every new exception a new class, but is there another way to do this?

No, there isn't another way. If you want to create a new exception type, you need a new class for it.

where to store them?

In a location that is accessible to all the code that will need to use them.

what am I doing if some exceptions are the same, just the name of the exception is changing a little bit?

Yep, still need to create a new class - though you can derive the new one from an existing exception class.

like image 98
Oded Avatar answered Sep 27 '22 17:09

Oded


Typically, for something like this I would create a single project or name space that would conntain all these custom exceptions (or even enums) that would be used throughout the project/solution.

This gives me a single point of reference/assembly to reference.

Further to your question about the exceptions with the same "look", I would create a base class that can be inherited by the other exceptions "with slightly different" names.

like image 39
Adriaan Stander Avatar answered Sep 27 '22 17:09

Adriaan Stander


You have to create new exception each time because this is how catch() works in try ... catch block to catch specific exception type. But I really like next approach taken from CLR via C# book:

public abstract class ExceptionArgs
{
    public string Message { get { return string.Empty; } }
}

[Serializable]
public class Exception<TExceptionArgs> : Exception, ISerializable
   where TExceptionArgs : ExceptionArgs
{

    private const String c_args = "Args";  // For (de)serialization
    private readonly TExceptionArgs m_args;

    public TExceptionArgs Args { get { return m_args; } }
    public Exception(String message = null, Exception innerException = null)
        : this(null, message, innerException) { }

    public Exception(TExceptionArgs args, String message = null,
       Exception innerException = null)
        : base(message, innerException) { m_args = args; }

    [SecurityPermission(SecurityAction.LinkDemand,
       Flags = SecurityPermissionFlag.SerializationFormatter)]
    protected Exception(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        m_args = (TExceptionArgs)info.GetValue(c_args, typeof(TExceptionArgs));
    }

    [SecurityPermission(SecurityAction.LinkDemand,
       Flags = SecurityPermissionFlag.SerializationFormatter)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(c_args, m_args);
        base.GetObjectData(info, context);
    }

    public override String Message
    {
        get
        {
            String baseMsg = base.Message;
            return (m_args == null) ? baseMsg : baseMsg + " (" + m_args.Message + ")";
        }
    }

    public override Boolean Equals(Object obj)
    {
        Exception<TExceptionArgs> other = obj as Exception<TExceptionArgs>;
        if (obj == null) return false;
        return Object.Equals(m_args, other.m_args) && base.Equals(obj);
    }
    public override int GetHashCode() { return base.GetHashCode(); }
}

Now will be able to create new args for exceptions like this:

public class ExceptionAExceptionArgs : ExceptionArgs
{
    //may add some properties if required here
}

And catch "new exceptions" like this:

try
{
   //do something here...
}
catch (Exception<ExceptionAExceptionArgs> ex)
{
}

I will make you to write less code for creation of new exceptions.
Please note: that this approach will not work if you would like to create hiearachy of exceptions where there is one base exception class and few child ones.
You may put exceptions classes enywhere you whant so the are accessible but it's good approach to create separate file for each.

like image 26
petro.sidlovskyy Avatar answered Sep 27 '22 16:09

petro.sidlovskyy