Hi guys, I have a question about error handling. Still working on the addition application and now that I've learned what are the correct exceptions to handle I'm not sure what to do when I've established that the my inputs are all valid and print my result. Let's have a look at the calculator class again:

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!");
        }*/
        catch(NumberFormatException numberFormatException){
            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!");
        }
        System.out.println("after the catches");
    }//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());
    }
}

So, I have a try/catch statement sitting inside the validateInputs() method which gets called when the button is clicked. Now, let's assume that my inputs are both valid, I need to display the result in my result text field.
So, where would I put the code that displays the result? Whether or not an exception is thrown, control is then returned to the first line after tha catch statement as far as I know, and if there isn't any, back to where the function containing the try catch block is: I need a way to determine whether an exception has been thrown or not and if it has, do nothing other than displaying the error (as I'm doing currently) and if it hasn't, displaying the result. So, what I thought I'd do, is that I could get my validateInputs() to return a boolean value of false if an exception has occurred and true if it hasn't, pass that back to the caller and take it from there. I can't think of any other way. Hope that makes sense.

the result textfield object instance is used in your try block to display the division result that u calculated there.

There's more than one way to do this. Figure out what you want validateInputs to do. Right now it's grabbing the Strings from the textboxes, parsing them into integers, doing the division, catching exceptions, and popping up error boxes. Now, do you want it to also fill in the answer box if all the tests pass (i.e. no exception is thrown). If so, it's doing everything there is to do, so put some code in there to put the answer in the answer box if and only if there are no exceptions, rename it to doDivision and keep it as a void function.

If it's supposed to validate the values only, then parse the textboxes into integers outside the function, pass the function two integers, and have the function return true if the input is valid and false otherwise, then fill in the answer box if and only if validateInputs returns true.

EDIT: Whoops. Deleted now irrelevant comments since they were in error since divisionResult is not local. Misread it originally as local.

Edited 4 Months Ago by AssertNull

I could get my validateInputs() to return a boolean value of false if an exception has occurred and true if it hasn't, pass that back to the caller and take it from there.

Without going into all the details, that sounds like a good idea.

In general it's a common practice to set some error flag in a catch block, or (if it's in a method) return an error value. You should always try to decouple logic (is this string a valid integer?) from user interface (what do i tell the user to do next if the input was invalid?)

thanks guys. Now, regardless of the way I do it, I still need a mechanism to determine whether the inputs are valid or not, that's where I think I got stuck, sorry maybe I didn't explain the issue correctly. So, for example, where I have the try/catch statement:

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(NumberFormatException numberFormatException){
                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!");
                }

say that the inputs are valid, my divisionResultgets the result and now it's just a matter of filling the text field with the value in divisionResult so I can just write something like result.setValue(parseInt(divisionResult));; trouble is though, wherever I do it, I still need a way to say "if the result is valid, then do result.setValue(parseInt(divisionResult));". So perhaps I can assign the result a value of 'null' inside the catch statements so I know that everytime the result is null it means that either the dividend or divisor, or both, are not valid and that gives me the condition I need, so I can write
if result !null then display the result

Edited 4 Months Ago by Violet_82

I still need a way to say "if the result is valid, then do result.setValue(parseInt(divisionResult));".

Wouldn't it be easiest to add the code between lines 2 and 3 above that executes if and only if no exception is thrown? That's the whole point of try-catch blocks. You put code that potentially throws an exception in the try block. If it does not throw an exception, all the code in the try block will execute. If an exception is thrown in the try block, the code in the try block STOPS executing and one of the catch blocks will execute.

    try{
                divisionResult = Integer.parseInt(getDividend()) /                        Integer.parseInt(getDivisor()));
                // code below gets executed if and only if no exception
                // thrown i.e. code to execute if valid input
                result.setValue(parseInt(divisionResult));
            }
            catch(ArithmeticException arithmeticException){
                System.err.println("Zero is an invalid denominator!");
                createError("Divisor can't be 0!! Please enter a number  > 0!");
            }       
            catch(NumberFormatException numberFormatException){
                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!");
                }

Edited 4 Months Ago by AssertNull

In a really trivial case like this there's no harm in putting it all in the try/catch, but moving forwards that's a bad practice because it doesn't scale at all. Keep the logic and the UI details separate.

I see, thanks. I think i might have had the wrong idea about the try/catch statement, that's why I didn't consider that option AssertNull.

You put code that potentially throws an exception in the try block

I took that literally, meaning that I'd put in there only the code that would trrow an exception, in this case divisionResult = ( Integer.parseInt(getDividend()) / Integer.parseInt(getDivisor())); and nothing else. Since result.setValue(parseInt(divisionResult)); doesn't throw an exception but it's a direct consequence of not having an exception, I wouldn't have ever considered to put it there, and I guess that's where I was stuck

My post for whatever reason has a bunch of white space on line 2. It looked fine when I posted it from another computer. My line 2 was supposed to be a copy/paste of your line 2. Lines 3, 4, and 5 were what I added.

I took that literally, meaning that I'd put in there only the code that would trrow an exception, in this case divisionResult = ( Integer.parseInt(getDividend()) / Integer.parseInt(getDivisor())); and nothing else.

Bold section of your quote isn't the way the try block works. You can have other code in the try block. The try block should contain at least one statement that contains a test that could potentially throw an exception, but not every statement in the try block needs to potentially throw an exception. The try-catch tutorial from Oracle contains this page that is similar to your case:

https://docs.oracle.com/javase/tutorial/essential/exceptions/putItTogether.html

They have helpfully bolded what is executed on that page. It is a good tutorial, so you might want to read the whole thing, not just the page I linked above. Relevant code section is below.

try 
{
    System.out.println("Entering try statement");
    out = new PrintWriter(new FileWriter("OutFile.txt"));
    for (int i = 0; i < SIZE; i++)
        out.println("Value at: " + i + " = " + list.get(i));
  }                        
  catch (IOException e) 
  {
    System.err.println("Caught IOException: " + e.getMessage());
  }

Line 4 potentially throws an IOException. If it does, then lines 5 and 6 will not execute. If everything is fine, lines 5 and 6 WILL execute. In my code below, line 2 below would be the equivalent of line 4 in the example above. Line 5 below would be the equivalent of lines 5 and 6 above. It will execute if and only if no exception was thrown earlier in the try block.

try{
            divisionResult = Integer.parseInt(getDividend()) / Integer.parseInt(getDivisor()));
            // code below gets executed if and only if no exception
            // thrown i.e. code to execute if valid input
            result.setValue(parseInt(divisionResult));
        }
        catch(ArithmeticException arithmeticException){
            System.err.println("Zero is an invalid denominator!");
            createError("Divisor can't be 0!! Please enter a number  > 0!");
        }       
        catch(NumberFormatException numberFormatException){
            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!");
            }

Edited 4 Months Ago by AssertNull

Yep I understand now, and I will give that turorial a good read too, thanks for clarifying things.

In python, there is an awesome else part in the try statement, so you can write for example

try:
    f = open('foo.txt', 'w')
except OSError:
    print('could not open file')
else:
    f.write('Hello there\n')
    f.close()
finally:
    print('executing finally')

The else part is only executed if the try part succeeded, and the finally part is always executed. The advantage is that exceptions thrown in the else part are not caught by the statement.
Is there no such feature in java ?

Edit: if I had to obtain the same result without the else part, I would do

file_opened = False
try:
    f = open('foo.txt', 'w')
    file_opened = True
except OSError:
    print('could not open file')
finally:
    try:
        if file_opened:
            f.write('Hello there\n')
            f.close()
    finally:
        print("executing finally")

The finally part makes it tricky, the code can be simplified without it. The same trick could be used in java.

Edit2: code update
Edit3: code update

Edited 4 Months Ago by Gribouillis

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