javaintellij-ideajavafxthrowable

Throwable argument 'ex' to 'System.out.println()' call


I am currently working on a stock management system. In the system there is option to register as seen below:

Registration page

The following code shows the register button method:

        btnRegister.setOnAction(e ->{// register button method
            try {
            Stage stage = new Stage();
            FXMLLoader loader = new FXMLLoader();
            Pane root =         loader.load(getClass().getResource("Register.fxml").openStream());
            RegisterController Msg = loader.getController();
            Scene scene = new Scene(root);
            scene.getStylesheets().setAll(
                getClass().getResource("style.css").toExternalForm()
            );
            stage.setScene(scene);
            stage.show();
            ((Node) e.getSource()).getScene().getWindow().hide();

            } catch (Exception ex) {
                System.out.println(ex);
            }
        });

I am getting the following warning:

Warning:(64, 36) Throwable argument 'ex' to 'System.out.println()' call

Could someone explain this warning and possible way to resolve this?

Will this have any impact later on with new changes if ignored?

It is complaining about the following line of the code from the register method specifically, where the exception is:

} catch (Exception ex) {
     System.out.println(ex);
}

Solution

  • You should be calling ex.printStackTrace() instead.

    Using System.out.println(ex) hides a lot of useful, possibly even pivotal, information. For example, if you run the following:

    package com.example;
    
    public class Main {
    
      public static void main(String[] args) {
        try {
          throwException();
        } catch (Exception ex) {
          System.out.println(ex);
        }
      }
    
      public static void throwException() throws Exception {
        throw new Exception("something went wrong");
      }
    }
    

    You get the following output:

    java.lang.Exception: something went wrong
    

    That only tells you the type of exception and the error message. For trivial applications that may be enough to know what and where the problem is. But consider a complex application with thousands of lines of code; this kind of exception reporting tells you nothing about where the problem occurred.

    Now replace System.out.println(ex) with ex.printStackTrace() and you'll see the new output:

    java.lang.Exception: something went wrong
        at com.example.Main.throwException(Main.java:14)
        at com.example.Main.main(Main.java:7)
    

    This is the stack trace. From a stack trace you can see the flow of execution and also see what specific line of code threw the exception. Note though that you can configure compilation to discard debugging information which means you'll stop getting source file names and line numbers, but you'll still be provided with class and method names (better than nothing).

    It goes further than this. Exceptions in Java can have a cause as well as multiple suppressed exceptions. This is described in greater detail by the Throwable documentation. Here's an (contrived) example:

    package com.example;
    
    import java.io.IOException;
    
    public class Main {
    
      public static void main(String[] args) {
        try {
          throwException();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    
      public static void throwException() throws Exception {
        IOException ioe = new IOException("could not write to stream");
        // typically suppressed exceptions come from a try-with-resources statement
        ioe.addSuppressed(new IOException("unable to close stream"));
    
        throw new Exception("something went wrong", ioe);
      }
    }
    

    This gives the following output:

    java.lang.Exception: something went wrong
        at com.example.Main.throwException(Main.java:19)
        at com.example.Main.main(Main.java:9)
    Caused by: java.io.IOException: could not write to stream
        at com.example.Main.throwException(Main.java:16)
        ... 1 more
        Suppressed: java.io.IOException: unable to close stream
            at com.example.Main.throwException(Main.java:17)
            ... 1 more
    

    If System.out.println(ex) was used instead then you wouldn't get either the Caused by: or Suppressed: sections. This means you have no idea what the actual problem is, nor if there are hidden problems, which, as you can probably imagine, makes it much more difficult to fix.

    There is another difference between System.out.println(ex) and ex.printStackTrace(). The former prints to the standard output stream (i.e. System.out) whereas the latter prints to the standard error stream (i.e. System.err). As an exception is an error it makes sense to print it to the error stream, but you can change the target via Throwable#printStackTrace(PrintStream) or Throwable#printStackTrace(PrintWriter). For instance, ex.printStackTrace(System.out) would print the stack trace to standarad output.

    And finally, for "real" applications you'll probably want to use a logging framework. These frameworks can output even more information, such as the thread the exception was reported by and the timestamp of when the exception occurred.


    Check out the What is a stack trace, and how can I use it to debug my application errors? Q&A to better understand stack traces and why they're useful.