How to throw an exception in Java that has already been caught in another catch like in Python?

In method setPhoneNumber how can I re-throw throw new InvalidPhoneNumber("Номер телефона должен состоять только из цифр") so that it could be caught as InvalidPhoneNumber?

public class App {
    public static void main(String[] args) {
        var person = new Person();
        var scanner = new Scanner(System.in);
        setPhoneNumber(person, scanner);
        System.out.println(person);
    }


    private static void setPhoneNumber(Person person, Scanner scanner) {
        System.out.print("Введите номер телефона в виде целого числа: ");
        var input = scanner.nextLine();
        long phoneNumber;
        String message;
        while (true) {
            try {
                phoneNumber = Long.parseLong(input);
                person.setPhoneNumber(phoneNumber);
                break;
            } catch (NumberFormatException e) {
                throw new InvalidPhoneNumber("Номер телефона должен состоять только из цифр");
            } catch (InvalidPhoneNumber e) {
                message = String.format("%s. Повторите ввод: ", e.getMessage());
                System.out.print(message);
                input = scanner.nextLine();
            }
        }
    }

If I run the code above, I receive an exception:

Connected to the target VM, address: '127.0.0.1:51614', transport: 'socket'
Введите номер телефона в виде целого числа: 12
Номер телефона (12) передан в некорректном формате. Повторите ввод: df
Exception in thread "main" ru.innopolis.homework.homework12.exceptions.InvalidPhoneNumber: Номер телефона должен состоять только из цифр
    at ru.innopolis.homework.homework12.App.setPhoneNumber(App.java:64)
    at ru.innopolis.homework.homework12.App.main (App.java:16)
Disconnected from the target VM. address: 1127.0.0.1:51614' transport. 'socket'

Upvotes: 0

Views: 90

Answers (2)

Stephen C
Stephen C

Reputation: 719376

You seem to be asking if you can throw an exception in a catch so that it can be caught in another catch of the same try. Java doesn't support that. Exceptions thrown in a catch clause are NOT handled by subsequent catch clauses for the same try.

One possible way to do what you are trying to do would be to use a nested try statement. For example.

try {
    try {
        // code that may throw InvalidPhoneNumber
    } catch (NumberFormatException e) {
        throw new InvalidPhoneNumber("Номер телефона должен состоять только из цифр");
    }
} catch (InvalidPhoneNumber e) {
    message = String.format("%s. Повторите ввод: ", e.getMessage());
    System.out.print(message);
    input = scanner.nextLine();
}

However, a lot of Java practitioners will look askance at the above. It can be argued that the above code is "using exceptions for flow control" which is considered to be poor Java style.

As dani-vta's answer illustrates, you can (typically) get a cleaner and more efficient solution in other ways.

Upvotes: 2

dani-vta
dani-vta

Reputation: 7130

It seems like that you would handle both cases (NumberFormatException and InvalidPhoneNumber) with the same code. Instead of having two separate catch blocks and trying to force one to handle the other (which is not possible, as it has already been said in the comments), you could pipe the two exceptions into a single catch block.

try {
    phoneNumber = Long.parseLong(input);
    person.setPhoneNumber(phoneNumber);
    break;
} catch (NumberFormatException | InvalidPhoneNumber e) {
    message = String.format("%s. Повторите ввод: ", e.getMessage());
    System.out.print(message);
    input = scanner.nextLine();
}

The multi-catch feature has been available since Java 7.

Upvotes: 3

Related Questions