Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 600
JavaDeveloper Avatar asked Jun 10 '13 01:06

JavaDeveloper


People also ask

How do you throw an exception for invalid input?

User-Defined Exception for Invalid Input in Java Let's create an exception if the user enters an ID. If it is not present in the database, the invalid id exception is thrown. The code creates an exception thrown when the input ID is invalid, which means not present in the database.

How do you throw an invalid exception in Java?

For example, we can check an input parameter to our method and throw an IllegalArgumentException if it is invalid: public void calculate(int n) { if (n > MAX_VALUE) { throw new IllegalArgumentException("Value too big (" + n + ")"); } ... }

What is the possible exception when it comes to input using scanner?

Whenever you take inputs from the user using a Scanner class. If the inputs passed doesn't match the method or an InputMisMatchException is thrown. For example, if you reading an integer data using the nextInt() method and the value passed in a String then, an exception occurs.

What type of exceptions can you throw?

We can throw either checked or unchecked exceptions. The throws keyword allows the compiler to help you write code that handles this type of error, but it does not prevent the abnormal termination of the program.


2 Answers

The question is is throwing illegal argument exception the 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 are returning null or returning a Point value that means "no such point" to the calling code. The problems with the 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".

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.

like image 144
Stephen C Avatar answered Oct 03 '22 00:10

Stephen C


This almost certainly should not throw an exception, because it makes perfect sense to invoke a method like this with any two Line values. You have already appropriately handled null values.

You have also, very reasonably, defined the behavior of your class in one of the ill-defined input situations, namely two coincident "constant" (horizontal) lines, where you return the point at x=0 on that line. You ought to similarly select return values for the other cases of ill-defined inputs: coinciding vertical lines, coinciding lines that are neither horizontal nor vertical, and non-coinciding parallel lines.

In my opinion, the most natural result for the last case - non-coinciding parallel lines - would be null, reflecting the fact that there is no point of intersection.

It would then be up to the client to decide whether a null intersection warrants an exception, an error message, or whatever. E.g. an interactive shell prompting the user for lines to intersect would probably print an error message and ask the user to try again. Some more complicated calculation, e.g. a linear optimizer trying to define boundaries for its search, might want to throw IllegalArgumentException if the constraints giving rise to the parallel lines contradict each other.

Of course, the return values in all these cases (coincident lines or non-coincident parallel lines) should be precisely documented in the method's javadoc.

like image 39
Andy Lowry Avatar answered Oct 03 '22 02:10

Andy Lowry