-1

This is my code:

    @Override
    public void start(Stage primaryStage) throws FileNotFoundException {
        System.out.print("Url gui successfully started.");
        final HBox hBox = new HBox();
        hBox.setSpacing(5);

        final TextField urlTextField = new TextField();
        urlTextField.setPromptText("Type Url Here");
        Button unblock = new Button("Unblock");
        Button block = new Button("Block");

        String hostsFile = BlockAndUnblock.getHostsFile();
        String blockedUrls = BlockAndUnblock.getBlockedUrls();
        boolean inSession = InSession.inSession > 0;
        try {
            unblock.setOnAction(event -> BlockAndUnblock.blockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession));
            block.setOnAction(event -> BlockAndUnblock.unBlockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("You encountered an IOException when trying to initiate the block and unblock buttons.");
        }

        ArrayList<String> urls = new ArrayList<String>();
        urls = readUrls();
        ListView listView = new ListView();
        listView.setId("Listview");
        for (String s: urls) {
            listView.getItems().add(s);
        }

        hBox.getChildren().add(listView);
        hBox.getChildren().add(urlTextField);
        hBox.getChildren().add(block);
        hBox.getChildren().add(unblock);
        hBox.setAlignment(Pos.CENTER_LEFT);
        hBox.setId("Urls");

        Scene scene = new Scene(hBox, 750, 500);
        scene.getStylesheets().addAll(this.getClass().getResource("../style.css").toExternalForm());
        primaryStage.setTitle("Urls");
        primaryStage.setScene(scene);

        primaryStage.show();
    }

The block and unblock methods it calls are these:

    public static void unBlockSite(String hostsFile, String blockedUrls, String url, boolean inSession) throws IOException {
        String file = Files.readString(Paths.get(hostsFile));
        file = file.replace("0.0.0.0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n","");
        file = file.replace("::0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n","");
        Files.writeString(Paths.get(blockedUrls), file, StandardOpenOption.TRUNCATE_EXISTING);
        if (inSession) {
            unBlock(hostsFile);
            block(hostsFile, blockedUrls);
        }
    }
    public static void blockSite(String hostsFile, String blockedUrls, String url, boolean inSession) throws IOException {
        if (inSession) unBlock(hostsFile);
        Files.writeString(Paths.get(blockedUrls), "0.0.0.0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n", StandardOpenOption.APPEND);
        Files.writeString(Paths.get(blockedUrls), "::0 " + url.substring(url.indexOf("//") + 2,url.length()-1) +"\n", StandardOpenOption.APPEND);
        if (inSession) block(hostsFile, blockedUrls);
    }

This is the error I'm getting:

site\java\BlockUrlsMenu.java:37: error: unreported exception IOException; must be caught or declared to be thrown unblock.setOnAction(event -> BlockAndUnblock.blockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession)); ^

site\java\BlockUrlsMenu.java:38: error: unreported exception IOException; must be caught or declared to be thrown block.setOnAction(event -> BlockAndUnblock.unBlockSite(hostsFile,blockedUrls,urlTextField.getText(), inSession)); ^

site\java\BlockUrlsMenu.java:39: error: exception IOException is never thrown in body of corresponding try statement } catch (IOException e) { ^

3 errors

What confuses me is that apparently BlockAndUnblock require me to catch or throw the IOException beforehand, but when I surround them in a try{} catch{} method it says they'll never throw an IOException. I also tried putting all the content of the start() method into a try{} catch{} block and it still gave me the first two errors.

Why is it telling me to catch an IOException and then saying it won't throw one?

Thanks for the help, I know this is a lot of code to go over.

1 Answers1

0

It's a lot of code so my analysis may be superficial, but I think it happens because .setOnAction() takes a Lambda expression.

Lambdas can't throw checked exceptions like IOException (hence the catch block becomes invalid and you get the third error, since the two lambdas can't actually throw), but at the same time your lambdas are calling two functions which throw themselves an IOException and you're not catching them inside the lambda (so you get the first and second error).

Try to change this:

try {
    unblock.setOnAction(event - > BlockAndUnblock.blockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
    block.setOnAction(event - > BlockAndUnblock.unBlockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
} catch (IOException e) {
    e.printStackTrace();
    System.out.println("You encountered an IOException when trying to initiate the block and unblock buttons.");
}

... into this:

try {
    unblock.setOnAction(event - > {
            try {
                BlockAndUnblock.blockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    block.setOnAction(event - > {
            try {
                BlockAndUnblock.unBlockSite(hostsFile, blockedUrls, urlTextField.getText(), inSession));
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
} catch (RuntimeException e) {
    e.printStackTrace();
    System.out.println("You encountered an IOException when trying to initiate the block and unblock buttons.");
}

With the above, inside each lambda you catch IOException and you wrap it inside a RuntimeException (which is unchecked so can be thrown by the lambda). In the outer catch, you catch the RuntimeException and do whatever you wanted to do initially with the IOException

Matteo NNZ
  • 11,930
  • 12
  • 52
  • 89