3

NOTE: This question is about finding a proper name for an exception where the condition for throwing the exception has not actually happened (eg. preventing a StackOverflow by throwing a StackOverflowException before an overflow can occur)

I have a FooList class that has bounds on the number of elements it can contain. The constructor takes an initial list of elements, and more elements can be added, up to the limit.

The question I have is this. Having a full FooList is not exceptional. I decided that it would probably be best if I provided the client with a way of checking to see if there was room in the FooList before trying to add something to it (hasRoom). However, this doesn't really stop them from calling add without checking first.

I decided that in this case, it may be appropriate to throw an exception. However, I'm not exactly sure what to call it. As I stated, having a full FooList is not particularly exceptional, and is in fact a perfectly valid state. So throwing a FooListFullException doesn't feel right. However, throwing an UnableToAddFooToListBecauseFooListIsFullException also doesn't feel right.

public class FooList {

    FooList(List<Foo> foos) {
        Objects.requireNonNull(foos);

        if (foos.size() > 6) {
            throw new IllegalArgumentException("foos must not contain more than 6 Foos");
        }

        if (foos.size() < 1) {
            throw new IllegalArgumentException("foos must contain at least 1 Foo");
        }

        this.foos = foos;
    }

    void add(Foo foo) {
        Objects.requireNonNull(foo);

        if (!hasRoom()) {
            throw new XException("no more room in list");
        }
    }

    boolean hasRoom() {
        return getNextEmptyIndex() != -1;
    }

    private List<Foo> foos;
}

In what way could I name the exception to indicate that an add operation is unable to complete, OR, is there a better way to get this across to the user/client?

  • How about MaximumNumberOfFooMembersExceededException ? By the way, your question speaks of Party all of a sudden instead of FooList. – Martin Maat Apr 23 '16 at 5:17
  • @MartinMaat Yeah, code from a different question. Fixed. – Zymus Apr 23 '16 at 5:23
  • Is there ever a case where two threads might add to the same list? If so, check then add doesn't avoid race conditions so failure to add is not exceptional. One idiom that might work is a reserveSpace call that returns an Optional<Settable<T>> which would avoid race conditions though another thread could still observe an unset element. – Mike Samuel Apr 23 '16 at 15:51
6

I think you're looking at this the wrong way.

You are correct that throwing an exception is the right thing to do. The fact that a full list is a valid state has little to do with the exception, though.

The exception in this situation is used to highlight that the state transition is invalid. That is to say, the caller is trying to push the object from a valid state to an invalid state.

I'm not a Java dev, so I don't know which specific exception to throw in this case. But, in C#, the InvalidOperationException is just for this kind of thing. Its MSDN entry reads "The exception that is thrown when a method call is invalid for the object's current state."

I'd recommend you follow that pattern when naming your exception. Make it clear the operation is invalid, not the state.

  • 2
    There is an IllegalStateException that, although the javadoc states it represents an illegal state in the JVM or java application, most people, even in the JRE, use it to represent that the object is in an illegal state for that method to be called. – Zymus Apr 23 '16 at 16:59
  • Java has UnsupportedOperationException, which fits the bill if you only read its description. But it's usually thrown by unimplemented methods of an interface (an antipattern from the early days of Java) and most Java programmers probably associate it with that. – Kevin Krumwiede Apr 27 '16 at 6:43
0

Exceptions are probably the best way to go. That way, whomever uses your class will get a well known, standardized notification that what they are attempting is a no no.

You should make your own custom Exception (e.g., OverFooListLimitException). Do include Exception at the end of your custom exception class name, so that everyone who sees it will know the purpose of this class.

public class MyOwnException extends Exception {
    public MyOwnException () {

    }

    public MyOwnException (String message) {
        super (message);
    }

    public MyOwnException (Throwable cause) {
        super (cause);
    }

    public MyOwnException (String message, Throwable cause) {
        super (message, cause);
    }
}

Replace the MyOwnException with whatever you name your custom exception.

Example Custom Exception came from How to create a custom exception type in Java?

  • I was thinking about FooLimitExceededException, at the same time however, the limit wasn't really exceeded, as the exception was thrown before it could be exceeded, which I think is where the problem lies. – Zymus Apr 23 '16 at 4:01
  • 2
    Here's another: FooListOverflowException. – Martin Maat Apr 23 '16 at 5:23
0

A Java Queue with a capacity limit throws an IllegalStateException. Personally, that seems like a poor choice of exception to throw, but you might want to do that to be "compatable" If you create your own Exception, consider extending IllegalStateException.

0

If I had to use an exception in this case, I would keep it as simple as possible and name it something like ContainerFullException or ListCapacityExceededException.

However, I'm not sure it's the best choice here. Since you've indicated that the list being full is actually not exceptional, that might be a good indicator not to use an exception. Exceptions can be expensive to throw (stack unwinding, etc.) and can, IMO, lead to more complex calling code.

Could add() on your list simply return a boolean which is true if the item was added and false otherwise? What is the calling code supposed to do if the list is full? If the value that couldn't be added has to be saved for retry later, this would be cleaner when working with a return value vs. trying to put logic in the catch block.

  • Might want to use "offer()" instead of add, as done by a Queue. – user949300 Apr 23 '16 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.