Bass3922
Bass3922

Reputation: 21

Java Program doesn't continue and Exception Error still appears after it is caught

This is a homework assignment where we have to debug and handle exceptions. I setup a try-catch to handle any input that isn't a double and the exception that comes up is caught, but it still prints the error. Here is my code:

import java.util.Scanner;
import java.util.InputMismatchException;

   public class Paint1 {

       public static void main(String[] args) {
           Scanner scnr = new Scanner(System.in);
           double wallHeight = 0.0;
           double wallWidth = 0.0;
           double wallArea = 0.0;
           double gallonsPaintNeeded = 0.0;
        
           final double squareFeetPerGallons = 350.0;
    
       do {
           System.out.println("Enter wall height (feet): ");
           try {
               wallHeight = scnr.nextDouble();
               throw new InputMismatchException();
           } catch (InputMismatchException exc) {
               System.out.println("Invalid input. Please try again.");
               wallHeight = scnr.nextDouble();
           }
       } while (wallHeight <= 0);
  
    ...
    ...
        
    }
}

and this is the output. Note: I used the number thirty spelled out to test the exception for the sake of the assignment.

Enter wall height (feet): 
thirty
Invalid input. Please try again.
Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:939)
    at java.base/java.util.Scanner.next(Scanner.java:1594)
    at java.base/java.util.Scanner.nextDouble(Scanner.java:2564)
    at Paint1.main(Paint1.java:24)

What am I missing or what do I have that I'm not supposed to?

Upvotes: 2

Views: 181

Answers (1)

Deepak Patankar
Deepak Patankar

Reputation: 3272

When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.

You will have to pass this token by yourself, you can use the next() function to read and pass this token. Since the token was not passed your code was again reading the same token and that's why you were getting InputMismatchException again.

do {
    System.out.println("Enter wall height (feet): ");
    try {
         wallHeight = scnr.nextDouble();
         throw new InputMismatchException();
     } catch (InputMismatchException exc) {
       System.out.println("Invalid input " + scnr.next() + ".Please try again.");
       wallHeight = scnr.nextDouble();
      }
} while (wallHeight <= 0);
System.out.println("WallHeight: " + wallHeight);

Input:

aaa
10

Output:

Enter wall height (feet): 
Invalid input aaa.Please try again.
WallHeight: 10.0

Still, this approach has an issue, What if the second value is invalid? Then it will throw the InputMismatchException, I would suggest to separate out the logic of reading input in a different function and that function should call itself when the input is wrong. Something like:

private Integer findValidIntValue(Integer numberOfChecks){
   if(numberOfChecks > MAXIMUM_CHECKS_ALLOWED){
      throw new InputMismatchException();
   }
   try {
        wallHeight = scnr.nextDouble();
     } catch (InputMismatchException exc) {
       System.out.println("Invalid input " + scnr.next() + ".Please try again.");
       return findValidIntValue(numberOfChecks + 1);
     }
}

Upvotes: 1

Related Questions