Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Local Development Environments Advanced Tooling Finishing TreeStory

Jonathan Mitten
PLUS
Jonathan Mitten
Courses Plus Student 11,197 Points

unreported exception IOException; must be caught or declared to be thrown

I have now wrapped any input with mReader in try/catch blocks, and even the main() input is wrapped up tight. I don't understand where this error is coming from. The code compiles and runs beautifully in the IDE.

I don't know why the tests are failing. Any insight would be appreciated.

com/teamtreehouse/Main.java
package com.teamtreehouse;

import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException{
    // write your code here
        try
        {
            Prompter prompter = new Prompter();
            String story;
            story = prompter.promptForStory();
            Template tmpl = new Template(story);
            prompter.run(tmpl);

        } catch (IOException ioe){
            ioe.printStackTrace();
        }
    }
}
com/teamtreehouse/Prompter.java
package com.teamtreehouse;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.io.IOException;

public class Prompter {
    private BufferedReader mReader;
    private Set<String> mCensoredWords;

    public Prompter() throws IOException{
        mReader = new BufferedReader(new InputStreamReader(System.in));
        loadCensoredWords();
    }

    private void loadCensoredWords()  {
        mCensoredWords = new HashSet<String>();
        Path file = Paths.get("resources", "censored_words.txt");
        List<String> words = null;
        try {
            words = Files.readAllLines(file);
        } catch (IOException e) {
            System.out.println("Couldn't load censored words");
            e.printStackTrace();
        }
        mCensoredWords.addAll(words);
    }

    public void run(Template tmpl) throws IOException{
        List<String> results = null;
        try {
            results = promptForWords(tmpl);
        } catch (IOException e) {
            System.out.println("There was a problem prompting for words");
            e.printStackTrace();
            System.exit(0);
        }
        String renderedResults = tmpl.render(results);
        System.out.printf("Your TreeStory:%n%n%s", renderedResults);
    }

    /**
     * Prompts user for each of the blanks
     *
     * @param tmpl The compiled template
     * @return
     * @throws IOException
     */
    public List<String> promptForWords(Template tmpl) throws IOException {
        List<String> words = new ArrayList<String>();
        try
        {
            for (String phrase : tmpl.getPlaceHolders()) {
                String word = promptForWord(phrase);
                words.add(word);
            }
        } catch (IOException ioe){
            ioe.printStackTrace();
        }
        return words;
    }

    public String promptForStory() throws IOException {
        System.out.printf("Tell me a story: %n");
        String story="";
        try{
            story = mReader.readLine();
        } catch (IOException ioe) {
            System.out.printf("Exception has been raised: %s", ioe);
        }
        return story;
    }

    /**
     * Prompts the user for the answer to the fill in the blank.  Value is guaranteed to be not in the censored words list.
     *
     * @param phrase The word that the user should be prompted.  eg: adjective, proper noun, name
     * @return What the user responded
     */
    public String promptForWord(String phrase) throws IOException{
        boolean uncensored = false;
        String s;
        try{
            do {
                System.out.printf("Enter a word for \"%s\":  %n", phrase);
                s = mReader.readLine();
                if (!mCensoredWords.contains(s))
                {
                    uncensored = true;
                } else {
                    uncensored = false;
                    System.out.printf("Sorry, %s is among the censored words. %n", s);
                }


            } while (!uncensored);
        } catch (IOException ioe){
            ioe.printStackTrace();
        }
        return s;
    }
}
pseudo-tests.md
#  This is essentially what I am testing 
1.  The user is prompted for a new string template (the one with the double underscores in it).

  a. The prompter class has a new method that prompts for the story template, and that method is called.

2.  The user is then prompted for each word that has been double underscored.

   a. The answer is checked to see if it is contained in the censored words.
      User is continually prompted until they enter a valid word

3.  The user is presented with the completed story

4 Answers

Jonathan Mitten
PLUS
Jonathan Mitten
Courses Plus Student 11,197 Points

I removed the throws IOException from the main() method to get the test running - which it does, but now with a new, undiscoverable error. I'll post a new thread for that.

Have you copied your code into the challenge and hit Preview?

Have you tried removing all your error handling and then building it back in step-by-step?

Ah, no, I was wrong ... the issue is 'noise' - the printf outputs are cluttering the challenge tests. It works fine if you remove those.

Jonathan Mitten
Jonathan Mitten
Courses Plus Student 11,197 Points

right, I figured out that my debug statements were causing the tests to fail, even after removing the main() throws IOException - so I've figured that all out, tests pass, course done! Thanks.

Good work. Glad you got it all fixed, and happy to have identified the issue with this thread's question. Enjoy your onward Java journey!

Hi Jonathan,

When you add throws Exception to the method signature, that requires that the exception is handled 'upstream' at the point where the method is called. If you leave the signature silent on this point, you can handle the exception within the method with your try/catch blocks, as you have done.

If you throw everything, at some point an upstream method call needs to handle the exception. Do you know which part of your code is creating the error? I note that main is throwing its exceptions - where to? I suspect that there's an error being thrown and not caught or you are declaring a throw when an error is undefined. Let's have a look at the error itself, and its position in your code, and go from there.

Steve.

Jonathan Mitten
Jonathan Mitten
Courses Plus Student 11,197 Points

Thanks for the reply. I don't know where the exception is being thrown, because I don't have the test script to run inside the IDE. I could debug that way. As far as I can tell, i'm handling all exceptions thrown all the way up through Main(), which is as upstream as I can see. I'm only using throws I/O exception on methods that use the mReader object. If I remove any of those exception handlers, I get different errors of exception and not being handled. In those cases, I'm unable to compile locally .

Maybe throwing from main means you no longer have an upstream position to handle the exception from? The caller of main needs to handle the exception main has delegated upstream.

What error do you get in Workspaces? Clicking the preview button may give you some info on that.

Jonathan Mitten
Jonathan Mitten
Courses Plus Student 11,197 Points

Unfortunately, there's no workspace that runs the same test script (the one that's throwing the error), and so just like with the IDE, it compiles fine and throws no errors. The program runs as expected.

This is a link to my workspace, recreated to match the code provided by the final IDE challenge.

I guess I would need to see the test script in order to continue to debug... or just randomly start removing error handling until the Treehouse script "takes", but I don't like stabbing in the dark.

OK - I copied your code into the challenge. I then deleted the throw on main as that is what was causing the error, as shown in the Preview pane.

After deleting that, I previewed again; it pointed to a different error because your returned value s had the potential to be uninitialised. I have initialised it where you declared it.

I then get an error about removing the TODO comments - I deleted the word TODO from comments.

Next, I get a warning about censored words. The word 'dork' is getting past.

Anyway, we've moved away from the IOException issue, so removing the main method's throw, for the reasons explained above, fixed that problem. There's other's that I will try to work through now.

Steve.