Would you Like to Throw Exceptions from a Constructor?

Throwing an exception from a constructor has always been an arguable issue between my friends after a few beers of joy. It firstly came to me on an exam where question was asking me to design a class which lets not more than n number of instances to be constructed.

Not using the most straight-forward trick to have a private constructor, I decided to invoke an exception from constructor if there exists more than n instances of that particular class. Luckily, I was coding in Java and had the comfort of a managed environment under the belt. My answer wasn’t graded thankfully but this case became a major concern and I decided to make several experiments back in the old days.

According to what I have seen while debugging, Java simply assigns a number of nulls or zeros to all of the fields of the class unless constructor is successfully executed. Additionally, right after an exception is thrown from a constructor, a null reference is returned and the newly created invalid instance starts to wait for the garbage collector to pick it up and remove the useless object from memory permanently. In short terms, a new instance is created although platform tends to murder it quickly in silent.

What about Unmanaged Platforms?

It was nice to see somebody was taking care of such exceptional situations but what would you do if you were alone? Fault tolerance isn’t just catching all exceptions: (from slides of Bjarne Stroustrup)

  1. The program must be in a valid state after an exception is caught
  2. Resource leaks must be avoided

This will become a problem where memory management is all up to you. You will have to remove and cleanup resources after an exception has been thrown, otherwise it will cause a leakage in memory and you will have created a zombie object hanging around memory — attached to the mother thread.

Cleaning Up the Mess of C++

An object is not even an object once its constructor finished successfully. So, better try to release resources inside the constructor before you throw an exception. In this case, I’m always using a double-exception throwing pattern that I made up and passionately using it in similar situations I face.

Let’s ask the complier! Two lines of code is always more representative than 10 lines of words. Here below, I’ve written a class called “Foo”, not functional but dangerous and an exception “StreamInitException” was decided to be thrown if there happens a problem while longStreamChar is being initialized. Right after we allocate 10k bytes for longStreamChar, BOOM! Someone pushed the wrong button, somebody shut down the database or trouble makers’ spirits are near. Don’t try to catch it inside the constructor and see what happens. Many orphan kids, once we named them as longStreamChar, are all around and we can’t even access them.

#include <iostream>

struct StreamInitException {
    StreamInitException(char * m){ message = m; }
    char * message;
};

class Foo {
    public:
        Foo(){
            try {
                this->initCharStream();
            } catch(StreamInitException * ex) {
                this->~Foo(); //release resources
                throw ex; // exception originally thrown by initCharStream
            }
        }

        ~Foo(){
            if(this->longCharStream)
            delete this->longCharStream;
        }

        void initCharStream(){
            //create a long char array of 10k
            this->longCharStream = (char*)malloc(10000);
            throw new StreamInitException("Error occurred during init.");
        }
    private:
        char * longCharStream;
    };

int main(){

    Foo * foo = NULL;

    try{
        foo = new Foo;
    } catch(StreamInitException * ex){
        std::cout << ex->message << std::endl;
    }

    return 0;

}

Therefore, I’m handling init related bad moments of the object inside the constructor, deallocate memory etc. and re-throw the same exception finally after I get the hold of the control. Seems acceptable!

Consequently, I have a final question: do you prefer to throw an exception from constructors or search for other workarounds such as assigning the workload to a separate method called Init()?

9 thoughts on “Would you Like to Throw Exceptions from a Constructor?

  1. Why don’t you integrate your idea with polymorphism to create a generic pattern? Image a single catch block to give back the resources allocated no matter which exception is thrown. Then, inside the same catch block, throw the same exception. Constructors might be surrounded by a large try/catch block all the time.

  2. Either the title of the post or your question as the epilogue is a leading question after illustrating the peculiarities of this path.

    Indication methodology for pre or postcondition faults via Exception or return values is not a matter of personal taste or can not be left to the preference of programmer in any sound repeatable development process (i.e: CMMI L3). Unless the underlying language’s style guide (e.g. PEP8) dictates a different semantic or Exception implementation is not unreasonably expensive, one should use Exceptions almost exclusively to indicate (and consequently handle) all faults.

    Speaking of the so called double-exception throwing, let’s say you didn’t made this up but rather explored. That’s more or less an application of popular structural pattern, Façade. This is a design decision which can be justified with the famous paper-boy analogy. The boy at your step, selling you today’s newspaper only hands you the newspaper and excepts you to return an exact amount of changes to complete the transaction. Let’s say you don’t have enough money to pay (technical: a resource problem) or actually you don’t have enough time today to read the paper thus an acquisition is pointless (functional: a business rule exception) or the newspaper is in Pig Latin and you can’t understand a shit (technical: missing implementation problem). None of these problems can be the concern of paper-boy. He won’t look at you wallet to check if you have enough money or not. He won’t check your schedule for today and consider on behalf of yourself if buying the newspaper is in the best interest of you for today nor he will make you a pop-quiz on the doorstep to check your language dexterity… Speaking of indicating the failures, as we set our return value type to “changes, couns” in this example, the paper-boy won’t understand (or even try to understand) return of NULL coins (read: no bucks for ya.) as and indication of error. Natural language exclusively uses Exceptions as error indicators. (e.g.: Sorry kiddie, I’ll be skipping today)

    In parallel with the paper-boy analogy, any direct API call (or message passing if you’d prefer) shouldn’t result an internal consistency problem in any way. Resource organization and fair allocation is not an exception (literally) either. If you didn’t have enough money to buy today’s newspaper and indicated your unwillingness to complete the transaction to paper-boy, you should close the door of your apartment and continue your life. Standing in the door step with an open door might be a significant resource leak in your daily routine.

    So, human life is unmanaged code and we execute all cleanup methods ourselves and luckily execution is almost instantaneous.

    Speaking of init():
    Epilogue question is two-fold and enters the dangerous realm of commonly abused method names. Probably init() is the most abused method name because of its sounding generality. A rule of thumb for using init() method is to handle all cross API boundary initialization and pre-condition checks in it. Expressively, an object requiring API border crossing (stepping out of the package) should have a post-construction initialization method. Such as connecting to a database, opening a socket, getting a syslog handler, setting up POSIX signal handling, etc. Cross-border calls in the constructor is a strong anti-pattern so does offloading the constructor’s pre-condition check, preliminary resource allocation, parameter localization (privatization) duties to another method (namely, init).

  3. Re: Erin

    Single catch block is like deploying the rat poison around with your daily cutlery set. You might be dead before your rat.

    Hitting into exceptions does not always indicate and unrecoverable error. So you might need to use them liberally.

    Here’s an example code in Python. A dynamic way to fit into the environment and provide backward compatibility. Exceptions in the constructor.


    def __init__(self, workers, urls):
    try:
    from multiprocessing import Process
    except ImportError, e:
    Process = Py25Compat.MPMimicProcess

    Nested exception handling might be possible in your platform but it’s not always readable from human point of view and no doubt it’s not vastly portable.

    The method, Burcu illustrated in the original post is readable, portable and have a lower memory impact for most VM environments. Although re-throwing the obscure technical exception bona fide might not be the suitable in every scenario but that’s OK for the simplicity sake.

  4. @Berk, I’m sharing the excitement you have for stealing my stage, here 🙂

    Let’s start with Façade. You absolutely have to dig deep in to find a treasure to catch a moment that this method is almost working as Façade. If it was, I’d like to hire a servant and only communicate with him/her, instead of waiting the paper boy to knock the door. Let’s say, my employees always are able to ask me if I have money or not, what’s good and bad with my schedule and my language preferences. Right after this point, it is his trouble to deal with the purchase, not mine anymore. In my case, I’m not acquiring a new interface; I’m hiring a paper boy myself. I have a tremendous feeling that division of memory allocation into a separate stage blurred your mind. Let’s me explain the story in other words again. During the execution of a constructor, its corresponding object is a lonely man who is supposed to live in an isolated island and holds a half-duplex phone (can access memory outside but no others are able to call him.) If a wild wild bird finally decides to taste a human, he should have to handle the bad to stay alive and call others outside to inform his passing away. So, nobody waits him anymore, doesn’t depend on him. But most importantly injured man has to kill the bird to avoid it from attacking other humans — it once tasted and recognized the good flavor. If he can’t kill, bird is going to fly away and nobody will be able to find it once again – risky for all human kind. So, kill and inform!

    A few sentences about “unmanaged human life”…
    Human life is not truly unmanaged; if it was, I’d be spending at least 75% of it with checking and testing. Regulations, laws, standards, etc. are out there to make it more formal and expected. If your friends’ choice over a prestigious, well-known and high standard restaurant makes you sick because of the dated fish, it is an exception. Normally you expect the food to be great. And it is fairly neither common nor practicable to carry a laboratory and food experts with you to check whatever you planning to eat.

  5. That’s totally a Facade pattern. You being in full flesh, standing on the door step is the Facade front interface itself. Paper-boy is the consumer of your interface, for the purpose of transaction. Your life is too complex for him to interface and also not fit for your security. To complete the transaction, you interface with your “wallet” object, your “schedule” object and your “interpreter” object to see if a transaction desirable or not. That might not conform to the formal definition of Facade pattern but actually it is a Facade. You can find a more complex version of this story in Martin Fowler’s EAI Patterns book under Facade on Service Oriented Services (?) section. Popularly, we call it ESB nowadays, as we shift from direct call space to inter-service communication.

    Let’s skip the gory stories and get to the bare technicals. I say your illustrated method is close to ideal. It’s perfectly OK to throw Exceptions from constructors, provided that no cruft left behind. I can only suggest, wrapping the internal exception into an API specific one instead of throwing the original exception.

    I guess you’re with me on the subject of creating init() methods, their semantic meaning and purposes.

    Re-visiting the Unmanaged Human Life…

    From the governing system (life) point of view. Human life is somewhat managed. Laws, regulations, police force, military and others are there for protection… I call it somewhat because life (as our VM) can not control and deny every chaotic action of a human. Ranging from killing another human (process), robbing a bank (resource limits), plan a military coup and execute it (total pwnage!) or fly a plane into a skyscraper killing tens of thousands. (denial of service).

    Returning to your example; from human point of view, he’s not exactly sure if he’s living in a VM or not. Ideally, if it was totally managed there should be no restaurant ratings and we should posses no fear about the security of our food or Ankara’s poisonous water or Melih Gokcek’s other possible actions to threaten human life. In the computers realm, in a VM we can’t be particular to any service and approach cautiously. Code blindly trusts. We humans don’t.

    Carrying around a lab and food engineers might be the analogy for high level vs low level languages. Actually we’re doing our best to check everything. Human body is like a comprehensive C library, carrying lots of utility functions and a somewhat secure operating system with extra error checks but anyway, we’re executing freely. Sniffing, seeing and matching with past experiences is not a VM service but a library. Things can go very bad with this library (i.e.: mental diseases) and that human process can totally ruin itself or effect others. In that point, we can’t talk about managed code anymore. And sorry that’s a fatal error rather than a soft exception raised by the VM.

    Again from human point of view, Regulations, laws and standards are enforced by the operating system, not necessarily by a VM. In a VM, it shouldn’t be possible for any part of code to override a resource or security policy. With our current operating systems it’s possible and even fun 🙂 Pretty much like real life.

    Why I said, “human life is unmanaged code” in my first reply… Because we still need to think about small, daunting details about resource allocation and our own security. I thought that leaving the door open was a clear example but after reading again, I accept it wasn’t that clear.

    A managed human life was illustrated in The Matrix. Actual human bodies were totally managed by the VM itself and the “code” was running smooth, thinking it’s running freely on an unmanaged system.

    The border is faded between virtualization and boxed environments. I’m sorry I’m not fit enough to elaborate more on these subjects; which in turn hurts my brain, increases my resource consumption of “philosophy” process, issuing “what is real” messages to a broadcast domain, causing congestion for my other services; thus resulting a denial of service for my personal existence system 🙂

  6. @Berk, I now clearly understand the way how it meets with Facade pattern. Sorry, may I have something wrong on mind to act persistently. I most probably lost my focus to see the big picture. That’s why I’m not promising to be a good software architect anytime soon.

    Unmanaged Human Life
    Obviously we both have rights and wrongs. Once we both picture the same scene in same perspective, I’m sure we are going to agree. Is life a VM or the underlying operating system? According to me, VM stands for regulations, standards blah blah and the obvious environment we live in stands for the operating system. The exceptions like hijacking or any failure in VM does not mean our life is unmanaged. You can’t guarantee VM to stay consistent forever and according to you, there is no managed platform – cause anything could happen anywhere. Think of me hacking your runtime stack, does this mean we are on a unmanaged platform? I’m wondering why your human life is VM.

    And anecdotes, I had a strong feeling that they were making it simpler to understand. I should re-visit my old decision now.

  7. I say do not throw exceptions from the constructor. Also, dont use exceptions as a part of your programming logic. Exceptions are costly.

Leave a comment