Click here to Skip to main content
14,304,866 members

Custom exceptions without constructor tedium (an alternative)

Rate this:
5.00 (4 votes)
Please Sign up or sign in to vote.
5.00 (4 votes)
1 Oct 2017CPOL
This is an alternative for "Custom exceptions without constructor tedium"

Introduction

Custom exceptions are tedius, with each one you create demanding five constructor overloads. Recently, and article was published here describing an interesting method for avoiding custom exception overload hell - Custom exceptions without constructor tedium, which utilized generics.

There is no code to download, and there aren't any screen shots in this article. Simply use the code snippets as the basis for your own implementation.

In my recent article series SQLXAgent - Jobs for SQL Express, I created what I think might be a simpler method for doing the same thing, is/can be application (or assembly) specific, and doesn't have the admittedly minor side-effect described in the other article.

The Code

Essentially, the idea is to create an enumerator that contains all ofthe possible exceptions that you want to define, a static class that instantiates and populates a dictionary, and a single custom exception class. The simplicity of it is that to add a new custom exception, you simply add a new enum item, and then a new dictionary item that describes it.

The enumerator looks like this (the actual list of exception codes will be dependent on your own requirements, so I didn't include all of mine here):

public enum SQLXExceptionEnum
{
    // JobThread/JobThreadManager excptions (0 - 99)
    Unknown=999,
    NoCmdLineArgs=1,
    CmdLineArgPkgFilename,
    PkgFileNotFound,
    CmdLineArgStepID,
    CmdLineArgPkgConnString,
    SQLXAgentConfigNotFound,
    SQLXAgentConnStringNotSpecified,
    QueryTextNullEmpty,
    PkgPathNullEmpty,

    // Package exceptions (100-199)
    NotSpecified=100,
    NoInitialCatalog,
    InvalidFileName,
    ImportFileNotFound,

    // ...
}

Next is the static class that maintains the listt of exception codes.

public static class SQLXExceptionCodes
{
    public static Dictionary<int, string> Codes { get; set; }

    static SQLXExceptionCodes()
    {
        SQLXExceptionCodes.Codes = new Dictionary<int,string>();
        Codes.Add((int)SQLXExceptionEnum.Unknown,                         "Unknown error - something bad happened that the application was not anticipating.");
        Codes.Add((int)SQLXExceptionEnum.NoCmdLineArgs,                   "No commandline arguments specified (expecting three).");
        Codes.Add((int)SQLXExceptionEnum.CmdLineArgPkgFilename,           "Commandline argument not specified - package filename");
        Codes.Add((int)SQLXExceptionEnum.PkgFileNotFound,                 "Specified package file not found");
        Codes.Add((int)SQLXExceptionEnum.CmdLineArgStepID,                "Commandline argument not specified - step ID");
        Codes.Add((int)SQLXExceptionEnum.CmdLineArgPkgConnString,         "Commandline argument not specified - package connectionstring");
        Codes.Add((int)SQLXExceptionEnum.SQLXAgentConfigNotFound,         "File not found - SQLXAgent.exe.config");
        Codes.Add((int)SQLXExceptionEnum.SQLXAgentConnStringNotSpecified, "SQLXAgent connection string not found in file SQLXAgent.exe.config");
        Codes.Add((int)SQLXExceptionEnum.QueryTextNullEmpty,              "SQL Step - query text is null or empty");
        Codes.Add((int)SQLXExceptionEnum.PkgPathNullEmpty,                "PKG Step - package path is null or empty");

        Codes.Add((int)SQLXExceptionEnum.NotSpecified,                    "Not specified");
        Codes.Add((int)SQLXExceptionEnum.NoInitialCatalog,                "InitialCatalog (Database) not found in connection string.");
        Codes.Add((int)SQLXExceptionEnum.InvalidFileName,                 "Filename cannot be null/empty");
        Codes.Add((int)SQLXExceptionEnum.ImportFileNotFound,              "Import source file not found");

        // ...
    }
}

And finally, the exception class itself. This is what you would have to do for each of the enums in the list if you wanted to create custom expression for all of them. In the SQLXAgent code, there were over 30 of these exception classes I would have had to write.

public class SQLXAgentException : Exception
{
    public int ReturnValue { get; set; }
    public SQLXAgentException()
    {
        this.ReturnValue = (int)SQLXExceptionEnum.NotSpecified;
    }
    public SQLXAgentException(string message) : base(message)
    {
        this.ReturnValue = (int)SQLXExceptionEnum.NotSpecified;
    }
    public SQLXAgentException(string message, Exception inner) : base(message, inner)
    {
        this.ReturnValue = (int)SQLXExceptionEnum.NotSpecified;
    }
    public SQLXAgentException(SQLXExceptionEnum result):base (SQLXExceptionCodes.Codes[(int)result])
    {
        this.ReturnValue = (int)result;
    }
    public SQLXAgentException(SQLXExceptionEnum result, Exception inner):base (SQLXExceptionCodes.Codes[(int)result], inner)
    {
        this.ReturnValue = (int)result;
    }
}

Usage

Usage is as you might expect it. There's nothing really weird you have to do to throw the exception, and handling it is like any other exception.

try
{
    throw new SQLXAgentException(SQLXExceptionEnum.SQLXAgentConfigNotFound);
}
catch (SQLXAgentException sex)
{
    MessageBox.Show(ex.Message);
}

History

  • 01 Oct 2017 - Initial publication.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

#realJSOP
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
Suggestionstands on its own, not an alternative Pin
edge94211-Oct-17 18:38
memberedge94211-Oct-17 18:38 
AnswerRe: stands on its own, not an alternative Pin
#realJSOP2-Oct-17 6:56
mve#realJSOP2-Oct-17 6:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Alternative
Article
Posted 1 Oct 2017

Tagged as

Stats

3.9K views
1 bookmarked