Search code examples
javaexception

Which exception to throw for invalid input which is valid from client perspective


I am writing code to find and intersection of 2 lines. When slopes of the lines are equal they dont intersect. But on the other hand an input with slopes of equal value is completely valid.

public static Point calculateIntersection(Line line1, Line line2) {

    if (line1 == null || line2 == null) {
        throw new NullPointerException(" some message ");
    }

    if (line1.getConstant() == line2.getConstant()) {
        return new Point(0, line1.getConstant());
    }

    if (line1.getSlope() == line2.getSlope()) {
        throw new IllegalArgumentException("slopes are same, the lines do not intersect.");
    }

    int x = (line2.getConstant() - line1.getConstant()) / (line1.getSlope() - line2.getSlope());
    int y = line1.getSlope() * x + line1.getConstant();

    return new Point(x, y);
}

The question is throwing illegal argument exception the right thing to do ? Since input is valid, it does not completely convince me.

Is custom exception the right thing to do ? Sounds like a good choice but an additional opinion would help.

Thanks


Solution

  • The question is is throwing illegal argument exception the right thing to do?

    There is no single "right thing to do". It depends on how you want / need to "frame" this condition; i.e. is it a bug, a user input error, or something that the program is supposed to be able to deal with?

    • If the case of two lines not intersecting is unequivocally a "bug", then IllegalArgumentException is fine. This is what the exception is designed for. (Note that it is an unchecked exception, so the expectation is that it won't be caught / recovered from.)

    • If this is a case that you expect the program to be able to recover from by itself, then a custom exception is the best idea. That way, you reduce the possibility of your code getting confused by (say) a library method throwing (say) an IllegalArgumentException ... than means something other than "two lines intersected".

    • If this case is something that you expect to report to the end user as part of input validation, then a generic "validation error" exception might be more appropriate than a specific custom exception. However, this method doesn't look like it is designed to be used (solely) for user input validation.


    In some contexts, it may be better to not throw an exception at all, but (IMO) this is not one of those contexts.

    The alternatives to throwing an exception are returning null or returning a Point value that means "no such point" to the calling code. The problems with these alternatives are:

    • If you return null the application has to deal with the null case ... or there will be NPEs.
    • There is no natural Point instance that could be used to mean "not a point"1.

    This is not to say that you couldn't make these alternatives work. It is just that in this context, it will probably be more work to do that, and probably there won't be a tangible pay-off.


    1 - I am assuming Point is java.awt.Point or similar. Obviously you could define and use a custom Point class which provides a "no such point" instance. But it will come at a cost. And you will need to deal with the case where code accidentally uses the "no such point" instance in some computation. And you are probably back where you started; i.e. throwing an exception!