Newbie1337's answer to his/hers own question is bringing a new information to this so I'll try to answer it according to the new information as best I can.
I recommend to read this article, which basically says, that one should use custom exceptions only if there is a good reason. Also here on SO is this post about why to use custom exceptions.
So first, we should find the reason for having a custom exception.
Imagine that we are creating some framework and we want the user to be able to catch all exceptions which may be thrown from it - so the exception have something to do with the functionality of the framework.
To do that we need to create a custom exception OurFrameworkException derived from Exception. (this exception should be probably abstract).
Not to be boring we can add an error code in it:
[Serializable]
public abstract OurFrameworkException : Exception
{
public int ErrorCode { get; private set; }
public OurFrameworkException(int errorCode)
{
ErrorCode = errorCode;
}
}
Then while we are implementing our framework we will get to the situation where there is a need of a custom exception.
Consider the framework to be a tool for code verification (poorly designed probably if following is possible). To get it working we will assume for the sake of the discussion, that we must first feed the framework with some rules and then run the verification it self and for some reason we can't do that in constructor. For example the rules may be changed dynamically. When there are no rules and the verification is run, we should probably throw an InvalidOperationException saying that we must first input the rules. But the original request stated above was, that all of the exceptions which are related to the framework should have a common base class to distinguish that they are related to it. So we need to implement OurFrameworkInvalidOperationException derived from OurFrameworkException:
[Serializable]
public OurFrameworkInvalidOperationException : OurFrameworkException
{
public OurFrameworkInvalidOperationException(string description)
: base(1) //for example
{
// store the description
}
}
Now for the sake of the discussion let's have this rather stupid implementation of our "framework".
public class OurFramework
{
string rules;
public void SetRules(string rules)
{
this.rules = rules;
}
public bool IsValid(string input)
{
if (!string.IsNullOrEmpty(rules)
{
return input == rules; //valid state is when the input is the same as the rules
}
else
{
throw new OurFrameworkInvalidOperationException("specify rules first");
}
}
}
And this is how someone would use our "very intelligent" framework:
OurFramework framework = new OutFramework();
//some inicialization
//the user should call here: framework.SetRules("rule");
bool isValid = false;
try
{
isValid = framework.Validate(input);
}
catch(OurFrameworkInvalidOperationException)
{
//tell the user that the rules are not filled in in the GUI somewhere.
}
catch(OurFrameworkOtherException)
{
//give the user a similar warning as previously about something else.
}
catch(OurFrameworkException)
{
//a general unspecified framework error occurred in the framework.
}
catch(Exception) //everything else
{
//something unrelated to the framework or unhandled in the framework occurred.
}
if (isValid)
{
//do stuff.
}
In the end this, here is one of many articles about how the custom exceptions should be implemented.