views:

215

answers:

8

I am trying to throw a (custom) ImportException from the method importUsers in class UserHelper. I can see in the debugger that the throw clause is executed, but the method, from which the importUsers method is called, never catches the exception.

Here is the method, where the exception is thrown:

public static AccessorValidator importUsers(List<String> data, WebUser actor) throws ImportException {

    //(irrelevant code removed)

    try {
        isSuccess = insertUserData(st, blocks, db, actor);
    } catch (Exception e) {
        throw new ImportException("Could not insert user on line " + rowCounter);
    }

}

Here I try unsuccessfully to catch the thrown exception from execute method in AccessorValidator class:

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    //(irrelevant code removed)
    try{
        av = UserHelper.importUsers(data, admin);
        System.out.print("test2");
    } catch (ImportException ie) {
        System.out.print("testE");
        returnMessageValue = ie.getMessage();
    } catch (Exception e) {
        System.out.print("testE2");
    }

The output is "test2", and the code execution never gets to either of the catch blocks. What do I do wrong?

A: 

perhaps insertUserData() doesn't throw any exception in your test setup? It would help if that method was included in your question as well...

takete.dk
It does. I mentioned that "I can see in the debugger that the throw clause is executed"; more specifically, I see in debugger that the code on line throw new ImportException("Could not insert user on line " + rowCounter);is executed.
simon
I didn't add the code from the insertUserData method, because the actual exception is thrown several levels deep, it would be complicated to follow.
simon
+1  A: 

If "test2" is printed, then there is no exception at all being thrown by importUsers().

The line information in the debugger can be inaccurate. Try putting a breakpoint in the constructor of the Exception to see if it's really being created.

Michael Borgwardt
A: 

Are you sure that insertUserData actually throws an exception, and not only returns a true/false boolean? Seeing the debugger step to a line with a "throw" does not mean that something is thrown, as the line information is not always completely accurate.

Lucero
+5  A: 

try changing your method to

try {
    isSuccess = insertUserData(st, blocks, db, actor);
    system.out.print("after insertUserData");
} catch (Exception e) {
    System.out.print("before throwing");
    throw new ImportException("Could not insert user on line " + rowCounter);
}

so that you can make sure that what you see in debug is what actually being executed (by checking your console), and whether insertUserData actually throws an exception or not.

Noam Gal
Thanks, this led me to the solution.
simon
A: 

Check the following, by order:

  1. check that your breakpoints are synchronized with the source code
  2. insertUserData() is not throwing an exception at all, verify if, at all, it should be throwing an exception or not. Looks like you are expecting something that never comes.
  3. Check that ImportException is indeed the same object in both cases you refer to it
Yuval A
A: 

If the output is "test2" then certainly the exception was not thrown.

Just guessing ...

Sometimes your IDE may not be synchronized with the source code that is actually executing, specially if your code is part of an external library... If you change the library's code and don't update the actual classpath, or if that change happens while debugging, the lines of code may change and you may be seeing the exception to be thrown although that isn't really happening.

bruno conde
A: 

Hi,

try to catch a Throwable, the root of Exception and Error, with:

try{
        av = UserHelper.importUsers(data, admin);
        System.out.print("test2");
    } catch (ImportException ie) {
        System.out.print("testE");
        returnMessageValue = ie.getMessage();
    } catch (Exception e) {
        System.out.print("testE2");
    } catch (Throwable t) {
        // Here you'll catch *anything* else
        System.out.print("testTE");
    }
ATorras
Generally you should only catch the exceptions that are relevant to the level that you're at, so be weary of long catch chains. That being said sometimes this very scenario is thrust upon us...
CurtainDog
A: 

Problem solved. It appears that the try-catch block in method importUsers was surrounded by another try-catch block, which did not throw the ImportException. So the first catch block was working correctly, I just missed the second one.

simon