views:

327

answers:

7

Is it legitimate to have exception handling code in a class constructor, or should it be avoided? Should one avoid having exception-generating code in a constructor?

+3  A: 

Assuming it's C++ you're talking about, raising exceptions is actually the only way to signal errors in a constructor - so this definitely shouldn't be avoided (*)

As to handling exceptions inside constructors, this is also perfectly valid, granted that you actually can handle the exception. Just follow the common rule here: catch exceptions at the level where you can handle them / do something meaningful about them.

(*) As long as you're not of the cult that avoids exceptions in C++

Eli Bendersky
+3  A: 

In C++, ctors are best placed to throw exceptions back up. FAQ:17.2

dirkgently
+3  A: 

Yes, it's perfectly reasonable. How else would you have a circumstance like this:

class List {
    public List(int length) {
        if(length < 0) {
            throw new ArgumentOutOfRangeException(
                "length",
                "length can not be negative"
            );
        }
        // okay, go!
    }
}

A List with negative length is most certainly exceptional. You can not let this get back to the caller and have them think that construction was successful. What's the alternative, a CheckIfConstructionSucceeded instance member function? Yucky.

Or what about

class FileParser {
    public FileParser(string path) {
        if(!File.Exists(path)) {
            throw new FileNotFoundException(path);
        }
        // okay, go!
    }
}

Again, this is a throw and nothing else is acceptable.

Jason
Shouldn't that code be in the property's (length) setter method?
froadie
@froadie: No way.
Jason
If length can never be negative, which is what it seems like if the constructor doesn't allow it to be, I would think there would be a setLength() setter method that enforces a valid length. What would be a reason to handle it in the constructor? (Am I missing something here?)
froadie
@froadie: Yes you are missing something. I am defining a `List` that has a constructor that allows me to specify the initial length (useful if I know how many items that I am going to insert and performance is critical so I don't want to worry about dynamic regrowths). The constructor absolutely has to check that the parameter `length` is a valid input for the state of the object. If you want to refactor that out into another method that can be shared with a property setter, fine, do so.
Jason
I see your point. Thanks for the edit. I've never implemented a constructor that can prevent construction - if a constructor fails (due to a thrown exception, as in your examples), what is the state of the object / object reference?
froadie
@froadie: would that be null?
born to hula
@froadie: That depends on the language but there are some very strong common principles among the most popular OOP languages (C++, C# and Java). I recommend reading Herb Sutter's "Constructor Exceptions in C++, C#, and Java" (http://bit.ly/9XoTQ0).
Jason
+3  A: 

I believe it's valid to throw an exception in a constructor to stop the creation of the object.

Vivin Paliath
+1  A: 

In general, I think that exception-generating code should be avoided whenever possible in constructors. This is very language specific, however - in some languages, constructors throwing an exception cause unrecoverable issues, but in some other languages, it's fine.

Personally, I try to make my constructors do as little as possible to put the object into a valid state. This would, in general, mean that they are not going to throw, unless it's a truly exception case (which I can't really handle anyways).

Reed Copsey
Well, of course it should be avoided when possible. That's a nearly trivial statement. Possible effectively means if object construction can proceed. If for any reason object construction can not proceed an exception should be thrown. I agree with your second paragraph.
Jason
@Jason: Technically, I think that's a bit harsh. That is not a trivial statement, since there are often design decisions that can be made in order to avoid throwing an exception in a constructor. It's up to the developer to decide what goes into a constructor, and what's passed as parameters to methods that will actually do work, etc.
Reed Copsey
So basically, you think that constructors should just do the minimal amount of work possible, and exception-handling code in a constructor should be rare?
froadie
@froadie: Yes. I personally feel that constructors should just do the bare necessity for the object to not be in an invalid state, at least when possible/practical.
Reed Copsey
+3  A: 

Anywhere there is the possibility of an exception being thrown, the "best practice" is to handle it, constructor or otherwise.

It does add another layer of complexity to the constructor, since you have to ensure everything is initialized correctly even if an error does occur, but it's better than having buggy code :)

Sheep Slapper
A: 

Sure, fail as early as you can! Inside constructors some validation of input params can go wrong, so it is defintely worth to fail, instead of proceeding with inconsistent built data.


Constructor(Param param){
  if(param == null)
    throw new IllegalArgumentException(...);
}

manuel aldana