Skip to main content

Exception Handling With Exception Policy

This is how I would think of an application at the very basic level:
Now this works great. But one thing that is missing in this picture is Exception Handling. In many cases we pay very less attention to it and take it as "we'll cross that bridge when it'll come to that". We can get away with this as in many application as exceptions does not stop it from being in the state "is the application working" as long as we code it carefully and at the very least handling the exceptions in code blocks.
This works. But we end up having try catch and if else everywhere and often with messy or no direction to what type of exception is to be handled where and how. Nonetheless, when it comes down an enhancement that depends upon different types exceptions, we will end up writing/modifying code every where, resulting in even messier code. I'm sure no one wants that. Even, in scenarios, a custom handler is not the answer either. Cause this way we will still need to make changes all over our code where we have used that handler.



The hero that can save us from this predicament is this namespace: á•™(`▿´)á•—
 Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
So the idea is very simple.
- Think about what kind of exceptions may occur in you application like read exception, write exception, heck even not implemented exception. (at the very least the  "awesome" application can have "awesomegenericexception"
- Define a policy for each. For each policy we'll have our own implementation or channel in to an existing implementation.
- apply these policies where necessary.

How it looks:
- in config:
<configSections>
    <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<exceptionHandling>
    <exceptionPolicies>
        <add name="AwesomeExceptionPolicy">
            <exceptionTypes>
                <add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                    postHandlingAction="ThrowNewException">
                    <exceptionHandlers>
                        <add name="Wrap Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WrapHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                            exceptionMessage="Awesome Exception Occured." exceptionMessageResourceType=""
                            exceptionMessageResourceName="Awesome Exception Occured. This is so awesome that you are going to get a text message for it :)."
                            wrapExceptionType="Awesome.Lib.Exceptions.AwesomeExceptionPolicyImpl, Awesome.Lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    </exceptionHandlers>
                </add>
            </exceptionTypes>
        </add>
    </exceptionPolicies>
</exceptionHandling>

- in code "the boss of exceptions":public class ExceptionManagerFactory : IProvider
{
    ExceptionManager exceptionManager;
    public Type Type
    {
        get
        {
            return this.GetType();
        }
    }
    public object Create(IContext context)
    {
        return GetExceptionManager();
    }
    public ExceptionManager GetExceptionManager()
    {
        if (exceptionManager == null)
        {
            IConfigurationSource config = ConfigurationSourceFactory.Create();
            ExceptionPolicyFactory factory = new ExceptionPolicyFactory(config);
            this.exceptionManager = factory.CreateManager();
        }
        return this.exceptionManager;
    }
}

- in code "the injection":Kernel.Bind<ExceptionManager>().ToProvider<ExceptionManagerFactory>().InSingletonScope();

- in code "the implementation":public class AwesomeExceptionPolicyImpl : ApplicationException
{
    public AwesomeExceptionPolicyImpl(string message)
        : base(message)
    { }     public AwesomeExceptionPolicyImpl(string message, Exception innerException)
        : base(message, innerException)
    {
        Console.WriteLine("to err is human :)");
    }
}
- in code "the use":
ExceptionManager exManager; // injection. Can be done in the super duper base class.
exManager.Process(() =>
{
 YouMyAwesomeTask();
}, "AwesomeExceptionPolicy");


private void YouMyAwesomeTask()
{
 // do the awesome task.
}


Here, I am only implementing the policy for System.Exception. But this can be for other exception types as well. Where the type does not need to be anything more than just a type or even just a message.


- So when it will come down to future modification we will only have to touch one class. Or in the worst case very little change in the code.
- And the overall outcome is even better you write less code. While implementing your method you only think about what policy does it fall under. How that is handled/implemented that's not your problem.
- Even you can make up policy as you go and implement them at later point or channel them to one implementation.
- And ofcourse, CLEAN CODE.

\ (•◡•) /

Comments

Popular posts from this blog

Openshift-Powered Homelab | Why, What, How

I wanted to build a Homelab for some time but it was taking a backseat as I always had access to cloud environments (eg: cloud accounts, VMware DC etc) and the use cases I was focusing on didn't really warrant for one. But lately, some new developments and opportunities in the industry triggered the need to explore use cases in a bare-metal server environment, ultimately leading to the built of my own homelab, called MetalSNO. In this post, I will discuss some of my key reasons for building a homelab, the goals I set for it, and the process I followed to building one from scratch. I'll conclude with some reflections on whether it was truly worth it and what I plan to do with it going forward. Compelling reasons (The Why ) My uses cases for a homelab weren't about hosting plex server, home automation etc (I have them on Raspberry PIs for some years now). My Homelab is really about exploring technologies and concepts that are on par with industry trend. Below are some of the ...

The story of a Hack Job

"So, you have hacked it" -- Few days ago one of the guys at work passed me this comment on a random discussion about something I built. I paused for a moment and pondered: Do I reply defending how that's not a hack. OR Do I just not bother I picked the second option for 2 reasons: It was late. It probably isn't worth defending the "hack vs" topic as the comment passed was out of context. So I chose the next best action and replied "Yep, sure did and it is working great.". I felt like Batman in the moment. In this post I will rant about the knowledge gap around hacking and then describe about one of the components of my home automation project (really, this is the main reason for this post) and use that as an example how hacking is cool and does not always mean bad. But first lets align on my definition of hacking: People use this term in good and bad, both ways. For example: "He/she did a hack job" -- Yeah, that probably...

Passwordless Auth to Azure Key Vault using External Secret and Workload Identity

I want to fetch my secrets from Azure KV and I don't want to use any password for it. Let's see how this can be implemented. This is yet another blog post (YABP) about ESO and Azure Workload Identity. Why Passwordless Auth: It is a common practice to use some sort of "master password" (spn clienid, clientsecret etc) to access Secret Vaults (in this case it is AZ KV) but that master password becomes a headache to manage (rotate, prevent leak etc). So, the passwordless auth to AKV is ideal.  Why ESO: This is discussed and addressed in the conclusion section. Workload Identity (Passwordless Auth): Lets make a backward start (just for a change). I will try to explain how the passwordless auth will work. This will make more sense when you will read through the detailed implementation section. Here's a sequence diagram to explain it: There's no magic here. This is a well documented process by microsoft  here . The below diagram (directly copied from the official doc...

Smart wifi controlled irrigation system using Sonoff and Home Assistant on Raspberry Pi - Part 1

If you have a backyard just for the sake of having one or it came with the house and you hate watering your garden or lawn/backyard then you have come to the right place. I genuinely believe that it is a waste of my valuable time. I would rather watch bachelorette on TV than go outside, turn on tap, hold garden hose in hand to water. Too much work!! Luckily, we have things like sprinkler system, soaker etc which makes things a bit easy. But you still have to get off that comfy couch and turn on tap (then turn off if there's no tap timer in place). ** Skip to the youtube video part if reading is not your thing   When I first moved into my house at first it was exciting to get a backyard (decent size), but soon that turned on annoyance when it came down maintaining it, specially the watering part. I laid bunch sprinklers and soaker through out the yard and bought tap timer but I still needed to routinely turn on the tap timer. Eventually few days ago I had enough of this rub...

Kubectl using SSH tunnel for TKG K8s Clusters

We know SSH'ing and probably many knows about SSH tunnel. The way, in my opinion, these 2 (SSH and SSH tunnel) are different to me (and I am in favor of SSH Tunnel) is how I use it. From tooling perspective I would almost always do tunnel instead of direct ssh.  In this post I will describe how to do SSH tunnel for kubectl to interact with remote kubernetes cluster (Specifically Tanzu Kubernetes Grid aka TKG cluster). Get the project ready to go from my github:  https://github.com/alinahid477/vsphere-with-tanzu-wizard Topics Backstory SSH tunnel for TKG Clusters using Docker container Technical stuff: Tunnel through Bastion for TKG K8s cluster Technical stuff: SSH Tunnel for Kubectl for remote K8s Clusters (same with or without docker) Technical stuff: Explain me this A famous quote from Darth Vader himself: "Feel the power of SSH Tunnel" Backstory Why ssh or ssh tunnel? The below diagram shows in what scenario a SSH or SSH Tunnel almost becomes a necessity. Let's st...

Jenkins on k8s - can it be this easy?

 As developers or devops we have had a somewhat love and hate relationship with Jenkins like "love oss based ci/cd that can be hosted on any environment with ranges of community plugins for pretty much anything" BUT "hate messy UI, lack of documentations, difficult to configure" etc etc. But this post isn't about pros and cons of Jenkins, rather it is about how you can get Jenkins on your k8s super quick and easy (using Merlin). Git Repo:  https://github.com/alinahid477/jenkinsonk8s Table of contents: Why Jenkins Why Merlin for Jenkins What is Merlin for Jenkins How Merlin for Jenkins works How Jenkins on k8s work Some anticipated FAQs Why Jenkins Jenkins remains a popular choice when it comes to CICD solution with a massive community of users and contributors (despite the fact there are new cool kids in block like Tekton etc). The way I see it (because of our love and hate relationship with it) "Jenkins is not CICD tool that you want it's the CICD t...