Hi guys,
I have a simple application which allows users to input a divisor, a divident and then calculates the quotient.
I'm using vaadin as framework but I don't think that matters.
So I've been thinking about the exceptions that can occurr and these are the ones i have identified:
-Division by 0: ArithmeticException;
-Users typing a string rather than a number: InputMismatchException
Here is the class that creates the form and deals with the exceptions (I'm not including the UI class as it's not needed):

package my.vaadin.project.exceptionTest;

import java.awt.Component;
import java.util.InputMismatchException;

import com.vaadin.server.Page;
import com.vaadin.shared.Position;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Notification;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.event.Action;

public class Calculation extends CustomComponent{
    final VerticalLayout vl = new VerticalLayout();
    final TextField dividend = new TextField();
    final TextField divisor = new TextField();

    final TextField result = new TextField();
    final Button resetButton = new Button("Reset");
    private int divisionResult = 0;
    Button button = new Button("Click Me");

    public Calculation(){
        dividend.setCaption("Enter the dividend:");
        divisor.setCaption("Enter the divisor:");

        result.setCaption("Result");
        result.setReadOnly(true); 
        button.addClickListener( new Button.ClickListener(){
            @Override
            public void buttonClick(ClickEvent event) {
                System.out.println("this is a test");   
                validateInputs();
            }            
        });
        resetButton.addClickListener(new Button.ClickListener(){            
            @Override
            public void buttonClick(ClickEvent event) {
                setDividend("");
                setDivisor("");             
                setResult("");
            }
        });
        vl.setMargin(true);
        vl.setSpacing(true);
        vl.addComponents(dividend, divisor, button, result );

    }//end of constructor
    public void validateInputs(){
        System.out.println("theDivisor is " + getDivisor() + " theDividend " + getDividend());
        try{
            divisionResult = ( Integer.parseInt(getDividend()) / Integer.parseInt(getDivisor()));
        }
        catch(ArithmeticException arithmeticException){
            System.err.println("Zero is an invalid denominator!");
            createError("Divisor can't be 0!! Please enter a number  > 0!");
        }
        catch(InputMismatchException inputMismatchException){
            System.err.println("The dividend or divisor are not a number! Please enter a valid number!");
            createError("The dividend or divisor are not a number! Please enter a valid number!");
        }
    }//end of validateInputs
    public String getDivisor(){     
        return divisor.getValue();
    }
    public String getDividend(){        
        return dividend.getValue();
    }
    public void setDivisor(String newDivisor){
        divisor.setValue(newDivisor);
    }
    public void setDividend(String newDividend){
        dividend.setValue(newDividend);
    }
    public void setResult(String newResult){
        result.setValue(newResult);
    }
    public void createError(String errorString){
        String error = errorString;
        Notification notif = new Notification(
                error,
                Notification.TYPE_ERROR_MESSAGE
            );
            notif.setDelayMsec(20000);
            notif.show(Page.getCurrent());
    }
}

I use the try catch statement when I calculate the quotient.
If I type 0 in the divisor then I get what I expect, an ArithmeticException is thrown and dealt with.
However, if I type a string in the fields I would have thought that the InputMismatchException would take care of it but in fact this is the message I get in the console:

Jul 10, 2016 10:46:26 PM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE: 
java.lang.NumberFormatException: For input string: "iuy"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at my.vaadin.project.exceptionTest.Calculation.validateInputs(Calculation.java:56)
    at my.vaadin.project.exceptionTest.Calculation$1.buttonClick(Calculation.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
    at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1008)
    at com.vaadin.ui.Button.fireClick(Button.java:377)
    at com.vaadin.ui.Button$1.click(Button.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:408)
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:79)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

I looked the NumberFormatException up and I'm not sure I understand what to do and why that happens. As you can see from the code I'm parsing the string to integers but it seems that the compiler doesn't like it. Do I have to add a catch statement and deal with the NumberFormatException too? Shouldn't the InputMismatchException be enough?
Please let me know what you think

Yes, you need to catch the NumberFormatException that's thrown when the user input is not numeric.

I would have thought that the InputMismatchException would take care of it

No. When in doubt, read the API documentation, eg

  • public static int parseInt(String s) throws NumberFormatException
    Parses the string argument as a signed decimal integer...
    Parameters:
    s - a String containing the int representation to be parsed
    Returns:
    the integer value represented by the argument in decimal.
    Throws:
    NumberFormatException - if the string does not contain a parsable integer.

Edited 4 Months Ago by JamesCherrill

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.