Monday, 21 September 2015

Custom Exceptions

There are numerous, exception classes provided check a list of existing Exceptions. If you can use one of these you probably should, however there may come a time when you need to create a custom exception class. To do so correctly you should following the following criteria
  1. Inherit from the Exception class: Custom exceptions should always inherit from the Exception class or one of its derived classes. This ensures that your custom exception can be caught and handled by catch blocks that are designed to handle exceptions.
  2. Provide three default constructors: Create three constructors that call their respective base implementations.
    • A parameter-less one
    • one that passes in a message 
    • one that passes in a message and an inner exception
  3. Provide a constructor that sets the message: It's a good practice to provide a constructor for your custom exception that sets the message. This allows you to provide a meaningful error message that describes the problem that caused the exception.
  4. Use a specific exception class for specific error: Create specific exception classes for specific errors, rather than using a general exception class for all errors. This allows you to handle specific errors in a more granular way and provides more information about what went wrong.
  5. Provide additional properties or methods: You can provide additional properties or methods on your custom exception class to provide more information about the error. This can be useful for logging or for displaying detailed error messages to the user.
  6. Use exception class name to reflect the error: You should use the exception class name to reflect the error, such as InvalidUserInputException, FileNotFoundException, etc.
  7. Provide inner exception: If you are wrapping an exception, you should provide the inner exception that caused the error, by using the constructor : base(message, innerException). This allows you to examine the original exception and understand the root cause of the problem.
  8. Document the exception: If you are creating a custom exception, it's important to document the exception, including when it might be thrown and what the possible causes of the exception are. This helps other developers understand how to use the exception and how to avoid throwing it.
Below is a contrived example of what a generic custom exception could look like


public class PersonException : Exception
{
    //Three Constructors are required by MS best practices

    //One empty
    public PersonException() { }

    //One that takes an error message associated with the Exception
    public PersonException(string msg) :
        base(msg) { }

    //one that takes the error message and and exception parameter
    //that wraps the original exception
    public PersonException(string msg, Exception inner) :
        base(msg, inner) { }

}


The above is the bare minimum you need to follow Microsoft best practices for custom exceptions. here's a full use leveraging our custom exception class.


using System.Text.RegularExpressions;

namespace pav.customException
{

    public class PersonException : Exception
    {
        //Three Constructors are required for MS best practices

        //One empty
        public PersonException() { }

        //One that takes an error message associated with the Exception
        public PersonException(string msg) :
            base(msg)
        { }

        //one that takes the error message and and exception parameter
        //that wraps the original exception
        public PersonException(string msg, Exception inner) :
            base(msg, inner)
        { }
    }
   
    class Person
    {
        private string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = CheckName(value);
            }
        }
        private string _lastName;

        public string LastName
        {
            get { return _lastName; }
            set { _lastName = CheckName(value); }
        }

        private string CheckName(string value)
        {
            if (Regex.IsMatch(value, @"^[a-zA-Z]{2,}$"))
                return value;
            throw new FormatException($"{value} is not a valid name");
        }
        public Person() {
            this._firstName = "";
            this._lastName = "";
         }

        public Person(string FirstName, string LastName) : this()
        {
            try
            {
                this.FirstName = FirstName;
                this.LastName = LastName;
            }
            catch (Exception ex)
            {
                throw new PersonException("A custom person exception", ex);
            }
        }
    }
   
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var p = new Person { FirstName = "Pawel", LastName = "Cicui2as" };
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            try
            {
                var p = new Person("Pawel", "CIucias2");
            }
            catch (PersonException ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.InnerException.Message);
            }
        }
    }
}


Remember that you really shouldn't need to create custom exceptions and should always try and leverage the standard c# ones, if you must create a custom exception, it's important to document it, including when it might be thrown and what the possible causes of the exception are. 

Saturday, 12 September 2015

Throw Exceptions

In our development there comes a time when we have to throw exceptions from our objects to communicate that there was a problem, for example if we have an object that has a problem, that object shouldn't really handle it, they should just let the consumer that something is wrong and let the consumer deal with it.


using System.Text.RegularExpressions;

namespace pc.exceptionThrowing
{
    class Person
    {
        private string _firstName = "";
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = CheckName(value);
            }
        }

        private string _lastName = "";
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = CheckName(value); }
        }

        private string CheckName(string value)
        {
            if (Regex.IsMatch(value, @"^[a-zA-Z]{2,}$"))
                return value;
            throw new FormatException($"{value} is not a valid name");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var p = new Person { FirstName = "Pawel", LastName = "Cicui2as" };
            }
            catch (FormatException ex) {
                Console.WriteLine(ex.Message);
            }
        }
    }
}


In the above example, we create a person class, and when we set the properties we test to see if the values provided are valid, and we throw a format exception if they're not. Our main program then catches those exceptions and handles them. It's important to understand that when an exception is thrown, the normal flow of the program is disrupted, any code after the throw statement will not be executed. It's a best practice to throw an exception as soon as you detect an error, rather than trying to continue executing the method and risk causing further problems, this also simplifies troubleshooting your code, the closer the exception is to the problem the easier it is to debug.

Keep in mind that exceptions should only be thrown in exceptional cases, as they carry some performance overhead. That is not to say that you shouldn't use, but just don't use them for logical flow... because that would be terrible.

Saturday, 5 September 2015

Exception handling

Writing defensive code is the pro-active effort of preventing exceptions, unfortunately not all exceptions are preventable, not all of them are fatal and often times they are in fact appropriate; regardless if exceptions are good or bad, they should always be handled with grace. The user experience is key, if your application crashes for any reason the odds of it being uninstalled increase exponentially.

You may wonder how do we handle exceptions? The answer is exception handling, which is implemented using try-catch blocks. The try block contains the code that may throw an exception, and the catch block contains the code that will handle the exception if it is thrown. The catch block is executed only if an exception is thrown in the try block.


namespace pav.exceptionHandling;
class Program
{
    static void Main(string[] args)
    {
        var str = "1d23";

        try
        {
            var i = int.Parse(str);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType() + ":" + ex.Message);
        }
    }
}


The above is a very simple example which catches our format exception, however you may notice that we are actually catching our base exception. The exception class is a catch all exception, it is the base exception of all exceptions,  It is best practice to catch your exceptions as specifically as possible


namespace pav.exceptionHandling;
class Program
{
    static void Main(string[] args)
    {
        var str = "1d23";

        try
        {
            var i = int.Parse(str);
        }
        catch (FormatException ex)
        {
            Console.WriteLine("format exctiption " + ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType() + ":" + ex.Message);
        }
    }
}


We left the (Exception ex) at the end to ensure that we catch anything that slipped through our exception chain. In this simple example we know the exception which will occur in our try block, however we may have for more complex code to test, which could through a number of different exceptions, each of which may need to be handled in a different way or at the very least provide exception specific information to the user or log.

We can also use the finally block, which is executed after the try block and all of its catch blocks, regardless of whether an exception was thrown or not. this is ideal in situations where you have to open some sort of stream in your try but an exception is thrown before you have a chance to close the stream, without the finally block you would create a memory leak which over time would crash your program.


namespace pav.exceptionHandling;
class Program
{
    static void Main(string[] args)
    {
        var str = "1d23";

        try
        {
            var i = int.Parse(str);
        }
        catch (FormatException ex)
        {
            Console.WriteLine("format exctiption " + ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType() + ":" + ex.Message);
        }
        finally
        {
            Console.WriteLine("Always print this");
        }
    }
}


In the above each catch block will only fire if the corresponding exception occurs inside our try block, however the finally block will always fire, exception or not.

It is possible to nest try-catch blocks, in nested try-catch blocks if an exception is thrown the innermost catch block will first try to handle the exception. however if the innermost catch block does not handle the exception, the next outer catch block is attempts to, and so on, until a catch block that can handle the exception is found. If no catch block can handle the exception, the exception propagates up the call stack until it is caught by a catch block in an outer try-catch block or until it is not caught and the program terminates.


namespace pav.exceptionHandling;

class Program
{
    static void Main(string[] args)
    {
        var str = "1d23";

        try
        {
            try
            {
                var i = int.Parse(str);
            }
            catch (FormatException ex)
            {
                throw;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType() + ":" + ex.Message);
        }
        finally
        {
            Console.WriteLine("Always print this");
        }
    }
}

Keep in mind that from a code readability angle, it's generally bad practice to use nested try-catch blocks, remember your goal is to write code that is efficient and simple. 

Tuesday, 1 September 2015

Defensive code

Defensive code is the concept of pro-actively catching errors before they occur, it puts the onus on the developer to write code that will prevent exceptions from occurring. Instead of taking data in and blindly casting it to the types we expect, we first check to ensure that the conversion won't throw an expectation.

We've already gone over this defensive code concept in practice earlier when we leveraged the tryParse or the 'is' or 'as' operators, all these constructs are here for us to prevent errors from occurring.

the idea behind defensive code is to prevent exceptions, our goal is to validate our data or what we are trying to do, before an exception is thrown. Hence we are ensuring that code which could though an exception, won't because it will never be executed.


using System;

namespace pc.defensiveCode
{
    class Person { }

    class Dog { }

    class Program
    {
        static void Main(string[] args)
        {
            var str = "12g3";
            int i;

            // We test to see if our 'str' variable is an int
            // rather than assume it is
            if (int.TryParse(str, out i))
                Console.WriteLine($"\"{str}\" is an int");
            else
                Console.WriteLine($"\"{str}\" is not an int");

            object o = DateTime.Now;

            // We test to see if our object 'o' is a DateTime
            // rather than assume it is
            if (o is DateTime)
                Console.WriteLine($"{o} is a valid date time");
            else
                Console.WriteLine("the value of o is not a valid date time");

            o = new Person();

            if (o is Person && o is Object)
                Console.WriteLine("o is a person and object");
            else
                Console.WriteLine("o is not a person and object");

            // We use the as operator to unbox our object
            // as a person
            var p = o as Person;

            // We test to see if our object 'p' is a not null
            // rather than assume it is
            if (p != null)
                Console.WriteLine("p is a person");
            else
                Console.WriteLine("p is not a person");


            // We use the as operator to unbox our object
            // as a dog
            var d = o as Dog;

            // We test to see if our object 'd' is a not null
            // rather than assume it is
            if (d != null)
                Console.WriteLine("d is a dog");
            else
                Console.WriteLine("d is not a dog");
        }
    }
}


this is more of a concept than a construct, but defensive code is good code.