salmonade
salmonade

Reputation: 7

A few problems with java input exception handling

I need to handle empty input and remove the stack trace from output.

Here's a snippet of my code:

public class TestShape
{
    public static void main(String args[])
    {

        for(int i = 0; i < args.length; i++)
        {
            try
            {
                Integer.parseInt(args[i]);
            }

            catch(NumberFormatException nfe)
            {
                System.err.println("\n" + "NumberFormatException is caught" + "\n" + "Please input 1, 2 or 3 valid numbers only");
            }

            if (args.length==0 ||args.length>3||Integer.parseInt(args[i])<0) 
                throw new IllegalArgumentException("\n" + "IllegalArgumentException is caught" + "\n" + "Please input 1, 2 or 3 valid numbers only");
        }

I have two problems, first is when a user inputs no value on the command line, it's supposed to throw a IllegalArguementException and the appropriate error message. When I run this code and input no values it runs without throwing the exception. It looks something like this:

C:\Users\XXX\Desktop\Folder>java TestShape

C:\Users\XXX\Desktop\Folder>_

The second problem is when I try out the other exceptions (putting a string instead of an int, negative numbers, exceeding more than 3 numbers etc.) it outputs the proper message but it also prints out the stack trace:

C:\Users\Chef Boi Logro\Desktop\Folder\ICS 112\Lab Exercises\LE8\New>java TestShape -1 2 -3

Exception in thread "main" java.lang.IllegalArgumentException:

IllegalArgumentException is caught Please input 1, 2 or 3 valid numbers only at TestShape.main(TestShape.java:19)

What I need is for the terminal to just display the error messages, without the stack trace.

Upvotes: 1

Views: 385

Answers (3)

Novdar
Novdar

Reputation: 348

You can check received values before checking for avoiding exceptions because you have expected numbers for the task (from 0 to 9);

I prefer this approach:

    public static void main(String args[])
    {
      if(arargs.length < 1 || arargs.length > 3) //firstly check input size
      {
        System.out.println("Please input 1, 2 or 3 valid numbers only.");
        return;
      }
      List<String> allowedNumbers = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); //define allowed numbers (please move to constant in your class for avoid multimple initialization)
        for(int i = 0; i < args.length; i++)
        {
          try
          {
            if(allowedNumbers.contains(args[i]))
            {
              Integer.parseInt(args[i]); //now it's safety parse without exceptions
            } 
          }
          catch(NumberFormatException nfe)
          {
            System.err.println(nfe.toString());
          }
        }
      }

Hope it's useful info.

Upvotes: 0

Aman
Aman

Reputation: 785

For the first problem, you are checking condition in wrong place. Refer given code for correction. For the second problem, you are using default exception handling which shows stack trace. For custom error handling, use throws clause. Refer given code for same.

Updated Code:

if (args.length < 1)
{
    throw new IllegalArgumentException("\n" + "IllegalArgumentException is caught" + "\n" + "Please input 1, 2 or 3 valid numbers only");
}
else
{
    for(int i = 0; i < args.length; i++)
    {
        if (args[i].matches("[0-9]+") && args[i].length() <= 3)
            {
                Integer.parseInt(args[i]);
            }
            else
            {
                throw new NumberFormatException("NumberFormatException is caught" + "\n" + "Please input 1, 2 or 3 valid numbers only");
            }
    }
}

Hope this will help. :-)

Upvotes: 0

Eran
Eran

Reputation: 394146

Your loop is not entered when no arguments are supplied, so no exception is thrown and nothing is displayed.

You should add a condition prior to the loop that throws an exception if args.length==0.

As for the stack trace being displayed, that's the default behavior for exception not handled by the main method. You'll have to catch all the exceptions you throw in order to avoid that.

Perhaps you should just replace

throw new IllegalArgumentException("\n" + "IllegalArgumentException is caught" + "\n" + "Please input 1, 2 or 3 valid numbers only");

with

System.err.println("\n" + "Please input 1, 2 or 3 valid numbers only");

since there's not much point in throwing exceptions from the main method (since there's no other method that can handle such exceptions).

Here's a suggested approach:

public static void main(String args[])
{
    if (args.length == 0 || args.length > 3) {
        System.err.println("Please input 1, 2 or 3 valid numbers only");
    } else {
        for(int i = 0; i < args.length; i++) {
            try {
                if (Integer.parseInt(args[i]) < 0) {
                    System.err.println("\n" + "Please input 1, 2 or 3 valid numbers only");
                }
            }
            catch(NumberFormatException nfe) {
                System.err.println("\n" + "NumberFormatException is caught" + "\n" + "Please input 1, 2 or 3 valid numbers only");
            }
        }
    }
}

Upvotes: 2

Related Questions