// Exceptions.java — try/catch/finally, try-with-resources and custom exceptions.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

public class Exceptions {

    // A custom checked exception for our domain
    static class InvalidOrderException extends Exception {
        InvalidOrderException(String message) { super(message); }
    }

    static int parseQuantity(String text) throws InvalidOrderException {
        try {
            int q = Integer.parseInt(text.trim());
            if (q <= 0) {
                throw new InvalidOrderException("Quantity must be positive: " + q);
            }
            return q;
        } catch (NumberFormatException e) {
            // Wrap the low-level error in a meaningful one, keeping the cause
            InvalidOrderException ex = new InvalidOrderException("Not a number: '" + text + "'");
            ex.initCause(e);
            throw ex;
        }
    }

    public static void main(String[] args) {
        for (String input : new String[] {"24", "-3", "abc"}) {
            try {
                System.out.println("Quantity: " + parseQuantity(input));
            } catch (InvalidOrderException e) {
                System.out.println("Rejected: " + e.getMessage());
            } finally {
                System.out.println("  (checked '" + input + "')");
            }
        }

        // try-with-resources closes the reader automatically, even on errors
        String csv = "id,qty\n1,24\n2,10";
        try (BufferedReader reader = new BufferedReader(new StringReader(csv))) {
            reader.readLine();                      // skip the header
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("Row -> " + line);
            }
        } catch (IOException e) {
            System.out.println("Could not read: " + e.getMessage());
        }
    }
}
