What is the difference between throw e and throw new Exception(e)?2019 Community Moderator Electiondifference...

Which aircraft had such a luxurious-looking navigator's station?

I am on the US no-fly list. What can I do in order to be allowed on flights which go through US airspace?

I can't die. Who am I?

Difference between 'stomach' and 'uterus'

How would one optimize conventional modern weapons for fighting robots

How to deny access to SQL Server to certain login over SSMS, but allow over .Net SqlClient Data Provider

Avoiding unpacking an array when altering its dimension

Is there a frame of reference in which I was born before I was conceived?

Why does the 31P{1H} NMR spectrum of cis-[Mo(CO)2(dppe)2] show two signals?

Why do members of Congress in committee hearings ask witnesses the same question multiple times?

What is the wife of a henpecked husband called?

Is there a ternary operator in math

When should a commit not be version tagged?

Replacement ford fiesta radiator has extra hose

What is the difference between throw e and throw new Exception(e)?

Can you use a beast's innate abilities while polymorphed?

Is there any relevance to Thor getting his hair cut other than comedic value?

"Murder!" The knight said

Did 5.25" floppies undergo a change in magnetic coating?

Hacker Rank: Array left rotation

Has the Isbell–Freyd criterion ever been used to check that a category is concretisable?

How to mitigate "bandwagon attacking" from players?

chrony vs. systemd-timesyncd – What are the differences and use cases as NTP clients?

Series pass transistor, LM7812



What is the difference between throw e and throw new Exception(e)?



2019 Community Moderator Electiondifference between throw and throw new Exception()What is exception wrapping in Java?Differences between HashMap and Hashtable?Does a finally block always get executed in Java?Catch multiple exceptions at once?How do you assert that a certain exception is thrown in JUnit 4 tests?What is the difference between public, protected, package-private and private in Java?Difference between StringBuilder and StringBufferDifference between wait() and sleep()Manually raising (throwing) an exception in PythonCatch multiple exceptions in one line (except block)Why is it faster to process a sorted array than an unsorted array?












20















Consider:



try  {
// Some code here
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}


What is the difference between throw e and throw new Exception(e)?



try  {
// Some code here
} catch (IOException e) {
throw new IOException(e);
} catch (Exception e) {
throw new Exception(e);
}









share|improve this question




















  • 6





    throw is followed by an expression resolving to a Throwable object. e is one Throwable object expression, and so is new Exception(e). The difference is just about how the throwable object is created. e is given to you by the catch block, and new Exception(e) is being created by your code.

    – ernest_k
    20 hours ago






  • 4





    in this example, it is pointless. however, if you want to use your own exception type, you could do catch(Exception e) { throw new MyException(e); } and this could make your exception handling code a lot easier/minimal

    – Stultuske
    20 hours ago






  • 3





    Former re-throws an already existing exception. Latter creates a new exception with e being the cause (see the documentation). Also called piggybacking. In the stacktrace you then see the exception and later down "caused by" followed by the stacktrace of the other exception.

    – Zabuza
    13 hours ago


















20















Consider:



try  {
// Some code here
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}


What is the difference between throw e and throw new Exception(e)?



try  {
// Some code here
} catch (IOException e) {
throw new IOException(e);
} catch (Exception e) {
throw new Exception(e);
}









share|improve this question




















  • 6





    throw is followed by an expression resolving to a Throwable object. e is one Throwable object expression, and so is new Exception(e). The difference is just about how the throwable object is created. e is given to you by the catch block, and new Exception(e) is being created by your code.

    – ernest_k
    20 hours ago






  • 4





    in this example, it is pointless. however, if you want to use your own exception type, you could do catch(Exception e) { throw new MyException(e); } and this could make your exception handling code a lot easier/minimal

    – Stultuske
    20 hours ago






  • 3





    Former re-throws an already existing exception. Latter creates a new exception with e being the cause (see the documentation). Also called piggybacking. In the stacktrace you then see the exception and later down "caused by" followed by the stacktrace of the other exception.

    – Zabuza
    13 hours ago
















20












20








20


4






Consider:



try  {
// Some code here
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}


What is the difference between throw e and throw new Exception(e)?



try  {
// Some code here
} catch (IOException e) {
throw new IOException(e);
} catch (Exception e) {
throw new Exception(e);
}









share|improve this question
















Consider:



try  {
// Some code here
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}


What is the difference between throw e and throw new Exception(e)?



try  {
// Some code here
} catch (IOException e) {
throw new IOException(e);
} catch (Exception e) {
throw new Exception(e);
}






java exception






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 12 hours ago









Peter Mortensen

13.7k1986113




13.7k1986113










asked 20 hours ago









Vinaya NayakVinaya Nayak

15111




15111








  • 6





    throw is followed by an expression resolving to a Throwable object. e is one Throwable object expression, and so is new Exception(e). The difference is just about how the throwable object is created. e is given to you by the catch block, and new Exception(e) is being created by your code.

    – ernest_k
    20 hours ago






  • 4





    in this example, it is pointless. however, if you want to use your own exception type, you could do catch(Exception e) { throw new MyException(e); } and this could make your exception handling code a lot easier/minimal

    – Stultuske
    20 hours ago






  • 3





    Former re-throws an already existing exception. Latter creates a new exception with e being the cause (see the documentation). Also called piggybacking. In the stacktrace you then see the exception and later down "caused by" followed by the stacktrace of the other exception.

    – Zabuza
    13 hours ago
















  • 6





    throw is followed by an expression resolving to a Throwable object. e is one Throwable object expression, and so is new Exception(e). The difference is just about how the throwable object is created. e is given to you by the catch block, and new Exception(e) is being created by your code.

    – ernest_k
    20 hours ago






  • 4





    in this example, it is pointless. however, if you want to use your own exception type, you could do catch(Exception e) { throw new MyException(e); } and this could make your exception handling code a lot easier/minimal

    – Stultuske
    20 hours ago






  • 3





    Former re-throws an already existing exception. Latter creates a new exception with e being the cause (see the documentation). Also called piggybacking. In the stacktrace you then see the exception and later down "caused by" followed by the stacktrace of the other exception.

    – Zabuza
    13 hours ago










6




6





throw is followed by an expression resolving to a Throwable object. e is one Throwable object expression, and so is new Exception(e). The difference is just about how the throwable object is created. e is given to you by the catch block, and new Exception(e) is being created by your code.

– ernest_k
20 hours ago





throw is followed by an expression resolving to a Throwable object. e is one Throwable object expression, and so is new Exception(e). The difference is just about how the throwable object is created. e is given to you by the catch block, and new Exception(e) is being created by your code.

– ernest_k
20 hours ago




4




4





in this example, it is pointless. however, if you want to use your own exception type, you could do catch(Exception e) { throw new MyException(e); } and this could make your exception handling code a lot easier/minimal

– Stultuske
20 hours ago





in this example, it is pointless. however, if you want to use your own exception type, you could do catch(Exception e) { throw new MyException(e); } and this could make your exception handling code a lot easier/minimal

– Stultuske
20 hours ago




3




3





Former re-throws an already existing exception. Latter creates a new exception with e being the cause (see the documentation). Also called piggybacking. In the stacktrace you then see the exception and later down "caused by" followed by the stacktrace of the other exception.

– Zabuza
13 hours ago







Former re-throws an already existing exception. Latter creates a new exception with e being the cause (see the documentation). Also called piggybacking. In the stacktrace you then see the exception and later down "caused by" followed by the stacktrace of the other exception.

– Zabuza
13 hours ago














4 Answers
4






active

oldest

votes


















35














If you don't need to adjust the exception type, you rethrow (throw further) the same instance without any changes:



catch (IOException e) {
throw e;
}


If you do need to adjust the exception type, you wrap e (as a cause) into a new exception of the type required.



catch (IOException e) {
throw new IllegalArgumentException(e);
}


I consider all other scenarios a code smell. Your second snippet is a good example of it.





Here are answers to the questions that might pop up.




Why would I want to rethrow an exception?




You can let it go. But if it happens, you won't be able to do anything at this level.



When we catch an exception in a method, we are still in that method and have access to its scope (e.g. local variables and their state). Before we rethrow the exception, we can do whatever we need to (e.g. log a message, send it somewhere, make a snapshot of the current state).




Why would I want to adjust an exception?




As a rule of thumb,




Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.



Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction




In other words, at some point, an obscure IOException should be transformed into a perspicuous MySpecificBusinessRuleException.



I called it "adjusting the exception type", smart guys call it exception translation (exception chaining, in particular).





To make it clear, let's have some folly examples.



class StupidExample1 {
public static void main(String[] args) throws IOException {
try {
throw new IOException();
} catch (IOException e) {
throw new IOException(new IOException(e));
}
}
}


results in a verbose stack trace like



Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
at StupidExample1.main(XXX.java:XX)
Caused by: java.io.IOException: java.io.IOException
... 1 more
Caused by: java.io.IOException
at StupidExample1.main(XXX.java:XX)


which can (and should) be effectively reduced to



Exception in thread "main" java.io.IOException
at StupidExample1.main(XXX.java:XX)


Another one:



class StupidExample2 {
public static void main(String[] args) {
takeString(new String(new String("myString")));
}

static void takeString(String s) { }
}


It's obvious that new String(new String("myString")) is a wordy version of "myString".






share|improve this answer

































    9














    catch (IOException e) {
    throw e;
    }


    You will see the original exception with the original stacktrace only. You won't see this "rethrow" line in the stacktrace so it's kind of transparent.



    catch (IOException e) {
    throw new IllegalStateException(e);
    }


    You will see created IllegalStateException and its stacktrace with "caused by" original exception information and stacktrace. You are setting (about to be) the thrown exception as the cause of the newly created IOException. The upper layer will see IllegalStateException and that will be possible to catch (you won't catch that catching cause exception).



    catch (IOException e) {
    throw new IOException();
    }


    You will see only the current stacktrace of the IOException creation, no the cause added.






    share|improve this answer


























    • When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

      – Tas
      8 hours ago











    • @Tas this is transparent as in "invisible".

      – Paŭlo Ebermann
      7 hours ago



















    2














    Well, basically, throw e will "rethrow" all original values- also some code-flow, which should be hidden, for example, security reason for instance. If you will re-create the exception, you will get - or you can get - another stacktrace in the place.



    So, I would say, you have option to mask some data (don't know, you can for example log exceptions into a special log, but you will want to pass other diagnostic data into end-user).



    Let's check the following a little:




    • I created one class as just only simple generator of Exceptions

    • another class allows to rethrow or recreate exception

    • afterwards, I am just printing the stacktrace and compare results


    Exception generator



    public class ExceptionsThrow {
    public static void throwNewException() throws Exception {
    throw new Exception("originally thrown message");
    }
    }


    Class for rethrow/ recreate exceptions



      public class Exceptions {

    public static void reThrowException() throws Exception {
    try {
    ExceptionsThrow.throwNewException();
    } catch (Exception e) {
    throw e;
    }
    }

    public static void reCreateNewException() throws Exception {
    try {
    ExceptionsThrow.throwNewException();
    } catch (Exception e) {
    throw new Exception(e);
    }
    }
    }


    Testing code example:



    try {
    Exceptions.reThrowException();
    } catch (Exception e) {
    System.out.println("1st RETHROW");
    e.printStackTrace();
    System.out.println("===========");
    }

    try {
    Exceptions.reCreateNewException();
    } catch (Exception e) {
    System.out.println("2nd RECREATE");
    e.printStackTrace();
    System.out.println("===========");
    }


    And the output finally:



    1st RETHROW
    java.lang.Exception: originally thrown message
    at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
    at test.main.stackoverflow.Exceptions.reThrowException(Exceptions.java:7)
    at test.main.MainTest.main(MainTest.java:110)
    java.lang.Exception: java.lang.Exception: originally thrown message===========
    2nd RECREATE

    at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:17)
    at test.main.MainTest.main(MainTest.java:118)
    Caused by: java.lang.Exception: originally thrown message
    at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
    at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:15)
    ... 1 more
    ===========


    In this case, you can see mostly the same data, but some additional, you can see the original message, because I have used the same Exception to built the new one, but you don't need to do it like this, so you can mask original cause, or you don't need to expose the logic of the application, for instance let’s check one more example:




    • I will take only the cause from the original exception, but it will override the data

    • as you can see, a newly created exception doesn't contain the full stacktrace, as the
      origin


    So:



    public static void maskException() throws Exception {
    try {
    ExceptionsThrow.throwNewException();
    } catch (Exception e) {
    throw new Exception("I will dont tell you",e.getCause());
    }
    }


    And the result:



    ===========
    3rd mask
    java.lang.Exception: I will don't tell you
    at test.main.stackoverflow.Exceptions.maskException(Exceptions.java:25)
    at test.main.MainTest.main(MainTest.java:126)
    ===========


    So, I would say, recreate the exception with the same instance is a little pointless, but there can be cases when you want to do it like that - mask data, or another case can be as well if you want to change Exception type - for example, from an I/O exception to a generic Exception, etc.



    In the real world, I can remember the really often issue, when some web portals, handled exceptions in PHP scripts only by this case of printing, and then usually, when the connection with the database was not working correctly, connection strings (including database address and credentials in plaintext) were visible in the web browser, for example. :)






    share|improve this answer

































      1














      This example doesn't make much sense in this context, because you're throwing the same exception and not doing anything else. Logging it at least will make much more sence. You're catching an exception to handle it or log it. If you cannot handle it, rethrow it (case 1) or wrap to something else (case 2).



      Case 1:



      public class Main {

      // forced to handle or rethrow again
      public static void main(String[] args) throws IOException {
      read();
      }

      public static void read() throws IOException {
      try {
      readInternal();
      } catch (IOException e) {
      throw e;
      }
      }

      private static void readInternal() throws IOException {
      throw new IOException("Output error");
      }
      }


      In the output you'll see something like:



      Exception in thread "main" java.io.IOException: Output error
      at com.alex.java.Main.readInternal(Main.java:26)
      at com.alex.java.Main.read(Main.java:19)
      at com.alex.java.Main.main(Main.java:14)
      **Case 2:**


      The pattern below allows you to change the type of the exception and keep the original exception details as well:



      try {
      // Some code here
      } catch (IOException e) {
      throw new IllegalStateException(e);
      }


      This case often happens when you would like to substitute a Checked Exception with an Unchecked exception preserving the origination of the issue and keep all the information (what called exception chaining).



      Regular use-cases:




      • You cannot handle a Checked Exception and you don't want to rethow it to the caller. Rethoring checked exceptions will force the caller to handle it. This is not what you want to do if there is no regular cases for recovery.

      • Exceptions like IOException are rarely useful to the client. You need to send something more specific and clear in scope of you business domain.


      IOException wrapped to Unchecked Exception like DocumentReadException will shed light on actual situation and will not force the callers to handle it:



      public class Main {

      public static void main(String[] args) {
      read();
      }

      public static void read() {
      try {
      readInternal();
      } catch (IOException e) {
      // log and wrap the exception to a specific business exception
      logger.error("Error reading the document", e);
      throw new DocumentReadException(e);
      }
      }

      private static void readInternal() throws IOException {
      throw new IOException("Output error");
      }
      }


      The output will be similar to:



      Exception in thread "main" java.lang.IllegalArgumentException: Error reading the document
      at com.alex.java.Main.read(Main.java:21)
      at com.alex.java.Main.main(Main.java:14)
      Caused by: java.io.IOException: Output error
      at com.alex.java.Main.readInternal(Main.java:26)
      at com.alex.java.Main.read(Main.java:19)
      ... 1 more


      As you can see from the stack-trace, the root cause was logger to help you find out the original problem and the business domain exception was sent to a user.






      share|improve this answer


























      • It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

        – Corrodias
        11 hours ago











      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54982437%2fwhat-is-the-difference-between-throw-e-and-throw-new-exceptione%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      35














      If you don't need to adjust the exception type, you rethrow (throw further) the same instance without any changes:



      catch (IOException e) {
      throw e;
      }


      If you do need to adjust the exception type, you wrap e (as a cause) into a new exception of the type required.



      catch (IOException e) {
      throw new IllegalArgumentException(e);
      }


      I consider all other scenarios a code smell. Your second snippet is a good example of it.





      Here are answers to the questions that might pop up.




      Why would I want to rethrow an exception?




      You can let it go. But if it happens, you won't be able to do anything at this level.



      When we catch an exception in a method, we are still in that method and have access to its scope (e.g. local variables and their state). Before we rethrow the exception, we can do whatever we need to (e.g. log a message, send it somewhere, make a snapshot of the current state).




      Why would I want to adjust an exception?




      As a rule of thumb,




      Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.



      Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction




      In other words, at some point, an obscure IOException should be transformed into a perspicuous MySpecificBusinessRuleException.



      I called it "adjusting the exception type", smart guys call it exception translation (exception chaining, in particular).





      To make it clear, let's have some folly examples.



      class StupidExample1 {
      public static void main(String[] args) throws IOException {
      try {
      throw new IOException();
      } catch (IOException e) {
      throw new IOException(new IOException(e));
      }
      }
      }


      results in a verbose stack trace like



      Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
      at StupidExample1.main(XXX.java:XX)
      Caused by: java.io.IOException: java.io.IOException
      ... 1 more
      Caused by: java.io.IOException
      at StupidExample1.main(XXX.java:XX)


      which can (and should) be effectively reduced to



      Exception in thread "main" java.io.IOException
      at StupidExample1.main(XXX.java:XX)


      Another one:



      class StupidExample2 {
      public static void main(String[] args) {
      takeString(new String(new String("myString")));
      }

      static void takeString(String s) { }
      }


      It's obvious that new String(new String("myString")) is a wordy version of "myString".






      share|improve this answer






























        35














        If you don't need to adjust the exception type, you rethrow (throw further) the same instance without any changes:



        catch (IOException e) {
        throw e;
        }


        If you do need to adjust the exception type, you wrap e (as a cause) into a new exception of the type required.



        catch (IOException e) {
        throw new IllegalArgumentException(e);
        }


        I consider all other scenarios a code smell. Your second snippet is a good example of it.





        Here are answers to the questions that might pop up.




        Why would I want to rethrow an exception?




        You can let it go. But if it happens, you won't be able to do anything at this level.



        When we catch an exception in a method, we are still in that method and have access to its scope (e.g. local variables and their state). Before we rethrow the exception, we can do whatever we need to (e.g. log a message, send it somewhere, make a snapshot of the current state).




        Why would I want to adjust an exception?




        As a rule of thumb,




        Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.



        Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction




        In other words, at some point, an obscure IOException should be transformed into a perspicuous MySpecificBusinessRuleException.



        I called it "adjusting the exception type", smart guys call it exception translation (exception chaining, in particular).





        To make it clear, let's have some folly examples.



        class StupidExample1 {
        public static void main(String[] args) throws IOException {
        try {
        throw new IOException();
        } catch (IOException e) {
        throw new IOException(new IOException(e));
        }
        }
        }


        results in a verbose stack trace like



        Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
        at StupidExample1.main(XXX.java:XX)
        Caused by: java.io.IOException: java.io.IOException
        ... 1 more
        Caused by: java.io.IOException
        at StupidExample1.main(XXX.java:XX)


        which can (and should) be effectively reduced to



        Exception in thread "main" java.io.IOException
        at StupidExample1.main(XXX.java:XX)


        Another one:



        class StupidExample2 {
        public static void main(String[] args) {
        takeString(new String(new String("myString")));
        }

        static void takeString(String s) { }
        }


        It's obvious that new String(new String("myString")) is a wordy version of "myString".






        share|improve this answer




























          35












          35








          35







          If you don't need to adjust the exception type, you rethrow (throw further) the same instance without any changes:



          catch (IOException e) {
          throw e;
          }


          If you do need to adjust the exception type, you wrap e (as a cause) into a new exception of the type required.



          catch (IOException e) {
          throw new IllegalArgumentException(e);
          }


          I consider all other scenarios a code smell. Your second snippet is a good example of it.





          Here are answers to the questions that might pop up.




          Why would I want to rethrow an exception?




          You can let it go. But if it happens, you won't be able to do anything at this level.



          When we catch an exception in a method, we are still in that method and have access to its scope (e.g. local variables and their state). Before we rethrow the exception, we can do whatever we need to (e.g. log a message, send it somewhere, make a snapshot of the current state).




          Why would I want to adjust an exception?




          As a rule of thumb,




          Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.



          Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction




          In other words, at some point, an obscure IOException should be transformed into a perspicuous MySpecificBusinessRuleException.



          I called it "adjusting the exception type", smart guys call it exception translation (exception chaining, in particular).





          To make it clear, let's have some folly examples.



          class StupidExample1 {
          public static void main(String[] args) throws IOException {
          try {
          throw new IOException();
          } catch (IOException e) {
          throw new IOException(new IOException(e));
          }
          }
          }


          results in a verbose stack trace like



          Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
          at StupidExample1.main(XXX.java:XX)
          Caused by: java.io.IOException: java.io.IOException
          ... 1 more
          Caused by: java.io.IOException
          at StupidExample1.main(XXX.java:XX)


          which can (and should) be effectively reduced to



          Exception in thread "main" java.io.IOException
          at StupidExample1.main(XXX.java:XX)


          Another one:



          class StupidExample2 {
          public static void main(String[] args) {
          takeString(new String(new String("myString")));
          }

          static void takeString(String s) { }
          }


          It's obvious that new String(new String("myString")) is a wordy version of "myString".






          share|improve this answer















          If you don't need to adjust the exception type, you rethrow (throw further) the same instance without any changes:



          catch (IOException e) {
          throw e;
          }


          If you do need to adjust the exception type, you wrap e (as a cause) into a new exception of the type required.



          catch (IOException e) {
          throw new IllegalArgumentException(e);
          }


          I consider all other scenarios a code smell. Your second snippet is a good example of it.





          Here are answers to the questions that might pop up.




          Why would I want to rethrow an exception?




          You can let it go. But if it happens, you won't be able to do anything at this level.



          When we catch an exception in a method, we are still in that method and have access to its scope (e.g. local variables and their state). Before we rethrow the exception, we can do whatever we need to (e.g. log a message, send it somewhere, make a snapshot of the current state).




          Why would I want to adjust an exception?




          As a rule of thumb,




          Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.



          Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction




          In other words, at some point, an obscure IOException should be transformed into a perspicuous MySpecificBusinessRuleException.



          I called it "adjusting the exception type", smart guys call it exception translation (exception chaining, in particular).





          To make it clear, let's have some folly examples.



          class StupidExample1 {
          public static void main(String[] args) throws IOException {
          try {
          throw new IOException();
          } catch (IOException e) {
          throw new IOException(new IOException(e));
          }
          }
          }


          results in a verbose stack trace like



          Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
          at StupidExample1.main(XXX.java:XX)
          Caused by: java.io.IOException: java.io.IOException
          ... 1 more
          Caused by: java.io.IOException
          at StupidExample1.main(XXX.java:XX)


          which can (and should) be effectively reduced to



          Exception in thread "main" java.io.IOException
          at StupidExample1.main(XXX.java:XX)


          Another one:



          class StupidExample2 {
          public static void main(String[] args) {
          takeString(new String(new String("myString")));
          }

          static void takeString(String s) { }
          }


          It's obvious that new String(new String("myString")) is a wordy version of "myString".







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 17 hours ago

























          answered 19 hours ago









          Andrew TobilkoAndrew Tobilko

          27.8k104388




          27.8k104388

























              9














              catch (IOException e) {
              throw e;
              }


              You will see the original exception with the original stacktrace only. You won't see this "rethrow" line in the stacktrace so it's kind of transparent.



              catch (IOException e) {
              throw new IllegalStateException(e);
              }


              You will see created IllegalStateException and its stacktrace with "caused by" original exception information and stacktrace. You are setting (about to be) the thrown exception as the cause of the newly created IOException. The upper layer will see IllegalStateException and that will be possible to catch (you won't catch that catching cause exception).



              catch (IOException e) {
              throw new IOException();
              }


              You will see only the current stacktrace of the IOException creation, no the cause added.






              share|improve this answer


























              • When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

                – Tas
                8 hours ago











              • @Tas this is transparent as in "invisible".

                – Paŭlo Ebermann
                7 hours ago
















              9














              catch (IOException e) {
              throw e;
              }


              You will see the original exception with the original stacktrace only. You won't see this "rethrow" line in the stacktrace so it's kind of transparent.



              catch (IOException e) {
              throw new IllegalStateException(e);
              }


              You will see created IllegalStateException and its stacktrace with "caused by" original exception information and stacktrace. You are setting (about to be) the thrown exception as the cause of the newly created IOException. The upper layer will see IllegalStateException and that will be possible to catch (you won't catch that catching cause exception).



              catch (IOException e) {
              throw new IOException();
              }


              You will see only the current stacktrace of the IOException creation, no the cause added.






              share|improve this answer


























              • When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

                – Tas
                8 hours ago











              • @Tas this is transparent as in "invisible".

                – Paŭlo Ebermann
                7 hours ago














              9












              9








              9







              catch (IOException e) {
              throw e;
              }


              You will see the original exception with the original stacktrace only. You won't see this "rethrow" line in the stacktrace so it's kind of transparent.



              catch (IOException e) {
              throw new IllegalStateException(e);
              }


              You will see created IllegalStateException and its stacktrace with "caused by" original exception information and stacktrace. You are setting (about to be) the thrown exception as the cause of the newly created IOException. The upper layer will see IllegalStateException and that will be possible to catch (you won't catch that catching cause exception).



              catch (IOException e) {
              throw new IOException();
              }


              You will see only the current stacktrace of the IOException creation, no the cause added.






              share|improve this answer















              catch (IOException e) {
              throw e;
              }


              You will see the original exception with the original stacktrace only. You won't see this "rethrow" line in the stacktrace so it's kind of transparent.



              catch (IOException e) {
              throw new IllegalStateException(e);
              }


              You will see created IllegalStateException and its stacktrace with "caused by" original exception information and stacktrace. You are setting (about to be) the thrown exception as the cause of the newly created IOException. The upper layer will see IllegalStateException and that will be possible to catch (you won't catch that catching cause exception).



              catch (IOException e) {
              throw new IOException();
              }


              You will see only the current stacktrace of the IOException creation, no the cause added.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 2 mins ago

























              answered 20 hours ago









              AntoniossssAntoniossss

              16.2k12354




              16.2k12354













              • When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

                – Tas
                8 hours ago











              • @Tas this is transparent as in "invisible".

                – Paŭlo Ebermann
                7 hours ago



















              • When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

                – Tas
                8 hours ago











              • @Tas this is transparent as in "invisible".

                – Paŭlo Ebermann
                7 hours ago

















              When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

              – Tas
              8 hours ago





              When something is referred to as "transparent" it means it's very clear; however, in your example it appears that since the stack trace would omit the re-throw, it's actually more vague or muddy. Is that correct?

              – Tas
              8 hours ago













              @Tas this is transparent as in "invisible".

              – Paŭlo Ebermann
              7 hours ago





              @Tas this is transparent as in "invisible".

              – Paŭlo Ebermann
              7 hours ago











              2














              Well, basically, throw e will "rethrow" all original values- also some code-flow, which should be hidden, for example, security reason for instance. If you will re-create the exception, you will get - or you can get - another stacktrace in the place.



              So, I would say, you have option to mask some data (don't know, you can for example log exceptions into a special log, but you will want to pass other diagnostic data into end-user).



              Let's check the following a little:




              • I created one class as just only simple generator of Exceptions

              • another class allows to rethrow or recreate exception

              • afterwards, I am just printing the stacktrace and compare results


              Exception generator



              public class ExceptionsThrow {
              public static void throwNewException() throws Exception {
              throw new Exception("originally thrown message");
              }
              }


              Class for rethrow/ recreate exceptions



                public class Exceptions {

              public static void reThrowException() throws Exception {
              try {
              ExceptionsThrow.throwNewException();
              } catch (Exception e) {
              throw e;
              }
              }

              public static void reCreateNewException() throws Exception {
              try {
              ExceptionsThrow.throwNewException();
              } catch (Exception e) {
              throw new Exception(e);
              }
              }
              }


              Testing code example:



              try {
              Exceptions.reThrowException();
              } catch (Exception e) {
              System.out.println("1st RETHROW");
              e.printStackTrace();
              System.out.println("===========");
              }

              try {
              Exceptions.reCreateNewException();
              } catch (Exception e) {
              System.out.println("2nd RECREATE");
              e.printStackTrace();
              System.out.println("===========");
              }


              And the output finally:



              1st RETHROW
              java.lang.Exception: originally thrown message
              at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
              at test.main.stackoverflow.Exceptions.reThrowException(Exceptions.java:7)
              at test.main.MainTest.main(MainTest.java:110)
              java.lang.Exception: java.lang.Exception: originally thrown message===========
              2nd RECREATE

              at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:17)
              at test.main.MainTest.main(MainTest.java:118)
              Caused by: java.lang.Exception: originally thrown message
              at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
              at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:15)
              ... 1 more
              ===========


              In this case, you can see mostly the same data, but some additional, you can see the original message, because I have used the same Exception to built the new one, but you don't need to do it like this, so you can mask original cause, or you don't need to expose the logic of the application, for instance let’s check one more example:




              • I will take only the cause from the original exception, but it will override the data

              • as you can see, a newly created exception doesn't contain the full stacktrace, as the
                origin


              So:



              public static void maskException() throws Exception {
              try {
              ExceptionsThrow.throwNewException();
              } catch (Exception e) {
              throw new Exception("I will dont tell you",e.getCause());
              }
              }


              And the result:



              ===========
              3rd mask
              java.lang.Exception: I will don't tell you
              at test.main.stackoverflow.Exceptions.maskException(Exceptions.java:25)
              at test.main.MainTest.main(MainTest.java:126)
              ===========


              So, I would say, recreate the exception with the same instance is a little pointless, but there can be cases when you want to do it like that - mask data, or another case can be as well if you want to change Exception type - for example, from an I/O exception to a generic Exception, etc.



              In the real world, I can remember the really often issue, when some web portals, handled exceptions in PHP scripts only by this case of printing, and then usually, when the connection with the database was not working correctly, connection strings (including database address and credentials in plaintext) were visible in the web browser, for example. :)






              share|improve this answer






























                2














                Well, basically, throw e will "rethrow" all original values- also some code-flow, which should be hidden, for example, security reason for instance. If you will re-create the exception, you will get - or you can get - another stacktrace in the place.



                So, I would say, you have option to mask some data (don't know, you can for example log exceptions into a special log, but you will want to pass other diagnostic data into end-user).



                Let's check the following a little:




                • I created one class as just only simple generator of Exceptions

                • another class allows to rethrow or recreate exception

                • afterwards, I am just printing the stacktrace and compare results


                Exception generator



                public class ExceptionsThrow {
                public static void throwNewException() throws Exception {
                throw new Exception("originally thrown message");
                }
                }


                Class for rethrow/ recreate exceptions



                  public class Exceptions {

                public static void reThrowException() throws Exception {
                try {
                ExceptionsThrow.throwNewException();
                } catch (Exception e) {
                throw e;
                }
                }

                public static void reCreateNewException() throws Exception {
                try {
                ExceptionsThrow.throwNewException();
                } catch (Exception e) {
                throw new Exception(e);
                }
                }
                }


                Testing code example:



                try {
                Exceptions.reThrowException();
                } catch (Exception e) {
                System.out.println("1st RETHROW");
                e.printStackTrace();
                System.out.println("===========");
                }

                try {
                Exceptions.reCreateNewException();
                } catch (Exception e) {
                System.out.println("2nd RECREATE");
                e.printStackTrace();
                System.out.println("===========");
                }


                And the output finally:



                1st RETHROW
                java.lang.Exception: originally thrown message
                at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
                at test.main.stackoverflow.Exceptions.reThrowException(Exceptions.java:7)
                at test.main.MainTest.main(MainTest.java:110)
                java.lang.Exception: java.lang.Exception: originally thrown message===========
                2nd RECREATE

                at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:17)
                at test.main.MainTest.main(MainTest.java:118)
                Caused by: java.lang.Exception: originally thrown message
                at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
                at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:15)
                ... 1 more
                ===========


                In this case, you can see mostly the same data, but some additional, you can see the original message, because I have used the same Exception to built the new one, but you don't need to do it like this, so you can mask original cause, or you don't need to expose the logic of the application, for instance let’s check one more example:




                • I will take only the cause from the original exception, but it will override the data

                • as you can see, a newly created exception doesn't contain the full stacktrace, as the
                  origin


                So:



                public static void maskException() throws Exception {
                try {
                ExceptionsThrow.throwNewException();
                } catch (Exception e) {
                throw new Exception("I will dont tell you",e.getCause());
                }
                }


                And the result:



                ===========
                3rd mask
                java.lang.Exception: I will don't tell you
                at test.main.stackoverflow.Exceptions.maskException(Exceptions.java:25)
                at test.main.MainTest.main(MainTest.java:126)
                ===========


                So, I would say, recreate the exception with the same instance is a little pointless, but there can be cases when you want to do it like that - mask data, or another case can be as well if you want to change Exception type - for example, from an I/O exception to a generic Exception, etc.



                In the real world, I can remember the really often issue, when some web portals, handled exceptions in PHP scripts only by this case of printing, and then usually, when the connection with the database was not working correctly, connection strings (including database address and credentials in plaintext) were visible in the web browser, for example. :)






                share|improve this answer




























                  2












                  2








                  2







                  Well, basically, throw e will "rethrow" all original values- also some code-flow, which should be hidden, for example, security reason for instance. If you will re-create the exception, you will get - or you can get - another stacktrace in the place.



                  So, I would say, you have option to mask some data (don't know, you can for example log exceptions into a special log, but you will want to pass other diagnostic data into end-user).



                  Let's check the following a little:




                  • I created one class as just only simple generator of Exceptions

                  • another class allows to rethrow or recreate exception

                  • afterwards, I am just printing the stacktrace and compare results


                  Exception generator



                  public class ExceptionsThrow {
                  public static void throwNewException() throws Exception {
                  throw new Exception("originally thrown message");
                  }
                  }


                  Class for rethrow/ recreate exceptions



                    public class Exceptions {

                  public static void reThrowException() throws Exception {
                  try {
                  ExceptionsThrow.throwNewException();
                  } catch (Exception e) {
                  throw e;
                  }
                  }

                  public static void reCreateNewException() throws Exception {
                  try {
                  ExceptionsThrow.throwNewException();
                  } catch (Exception e) {
                  throw new Exception(e);
                  }
                  }
                  }


                  Testing code example:



                  try {
                  Exceptions.reThrowException();
                  } catch (Exception e) {
                  System.out.println("1st RETHROW");
                  e.printStackTrace();
                  System.out.println("===========");
                  }

                  try {
                  Exceptions.reCreateNewException();
                  } catch (Exception e) {
                  System.out.println("2nd RECREATE");
                  e.printStackTrace();
                  System.out.println("===========");
                  }


                  And the output finally:



                  1st RETHROW
                  java.lang.Exception: originally thrown message
                  at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
                  at test.main.stackoverflow.Exceptions.reThrowException(Exceptions.java:7)
                  at test.main.MainTest.main(MainTest.java:110)
                  java.lang.Exception: java.lang.Exception: originally thrown message===========
                  2nd RECREATE

                  at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:17)
                  at test.main.MainTest.main(MainTest.java:118)
                  Caused by: java.lang.Exception: originally thrown message
                  at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
                  at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:15)
                  ... 1 more
                  ===========


                  In this case, you can see mostly the same data, but some additional, you can see the original message, because I have used the same Exception to built the new one, but you don't need to do it like this, so you can mask original cause, or you don't need to expose the logic of the application, for instance let’s check one more example:




                  • I will take only the cause from the original exception, but it will override the data

                  • as you can see, a newly created exception doesn't contain the full stacktrace, as the
                    origin


                  So:



                  public static void maskException() throws Exception {
                  try {
                  ExceptionsThrow.throwNewException();
                  } catch (Exception e) {
                  throw new Exception("I will dont tell you",e.getCause());
                  }
                  }


                  And the result:



                  ===========
                  3rd mask
                  java.lang.Exception: I will don't tell you
                  at test.main.stackoverflow.Exceptions.maskException(Exceptions.java:25)
                  at test.main.MainTest.main(MainTest.java:126)
                  ===========


                  So, I would say, recreate the exception with the same instance is a little pointless, but there can be cases when you want to do it like that - mask data, or another case can be as well if you want to change Exception type - for example, from an I/O exception to a generic Exception, etc.



                  In the real world, I can remember the really often issue, when some web portals, handled exceptions in PHP scripts only by this case of printing, and then usually, when the connection with the database was not working correctly, connection strings (including database address and credentials in plaintext) were visible in the web browser, for example. :)






                  share|improve this answer















                  Well, basically, throw e will "rethrow" all original values- also some code-flow, which should be hidden, for example, security reason for instance. If you will re-create the exception, you will get - or you can get - another stacktrace in the place.



                  So, I would say, you have option to mask some data (don't know, you can for example log exceptions into a special log, but you will want to pass other diagnostic data into end-user).



                  Let's check the following a little:




                  • I created one class as just only simple generator of Exceptions

                  • another class allows to rethrow or recreate exception

                  • afterwards, I am just printing the stacktrace and compare results


                  Exception generator



                  public class ExceptionsThrow {
                  public static void throwNewException() throws Exception {
                  throw new Exception("originally thrown message");
                  }
                  }


                  Class for rethrow/ recreate exceptions



                    public class Exceptions {

                  public static void reThrowException() throws Exception {
                  try {
                  ExceptionsThrow.throwNewException();
                  } catch (Exception e) {
                  throw e;
                  }
                  }

                  public static void reCreateNewException() throws Exception {
                  try {
                  ExceptionsThrow.throwNewException();
                  } catch (Exception e) {
                  throw new Exception(e);
                  }
                  }
                  }


                  Testing code example:



                  try {
                  Exceptions.reThrowException();
                  } catch (Exception e) {
                  System.out.println("1st RETHROW");
                  e.printStackTrace();
                  System.out.println("===========");
                  }

                  try {
                  Exceptions.reCreateNewException();
                  } catch (Exception e) {
                  System.out.println("2nd RECREATE");
                  e.printStackTrace();
                  System.out.println("===========");
                  }


                  And the output finally:



                  1st RETHROW
                  java.lang.Exception: originally thrown message
                  at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
                  at test.main.stackoverflow.Exceptions.reThrowException(Exceptions.java:7)
                  at test.main.MainTest.main(MainTest.java:110)
                  java.lang.Exception: java.lang.Exception: originally thrown message===========
                  2nd RECREATE

                  at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:17)
                  at test.main.MainTest.main(MainTest.java:118)
                  Caused by: java.lang.Exception: originally thrown message
                  at test.main.stackoverflow.ExceptionsThrow.throwNewException(ExceptionsThrow.java:5)
                  at test.main.stackoverflow.Exceptions.reCreateNewException(Exceptions.java:15)
                  ... 1 more
                  ===========


                  In this case, you can see mostly the same data, but some additional, you can see the original message, because I have used the same Exception to built the new one, but you don't need to do it like this, so you can mask original cause, or you don't need to expose the logic of the application, for instance let’s check one more example:




                  • I will take only the cause from the original exception, but it will override the data

                  • as you can see, a newly created exception doesn't contain the full stacktrace, as the
                    origin


                  So:



                  public static void maskException() throws Exception {
                  try {
                  ExceptionsThrow.throwNewException();
                  } catch (Exception e) {
                  throw new Exception("I will dont tell you",e.getCause());
                  }
                  }


                  And the result:



                  ===========
                  3rd mask
                  java.lang.Exception: I will don't tell you
                  at test.main.stackoverflow.Exceptions.maskException(Exceptions.java:25)
                  at test.main.MainTest.main(MainTest.java:126)
                  ===========


                  So, I would say, recreate the exception with the same instance is a little pointless, but there can be cases when you want to do it like that - mask data, or another case can be as well if you want to change Exception type - for example, from an I/O exception to a generic Exception, etc.



                  In the real world, I can remember the really often issue, when some web portals, handled exceptions in PHP scripts only by this case of printing, and then usually, when the connection with the database was not working correctly, connection strings (including database address and credentials in plaintext) were visible in the web browser, for example. :)







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 11 hours ago









                  Peter Mortensen

                  13.7k1986113




                  13.7k1986113










                  answered 19 hours ago









                  xxxvodnikxxxxxxvodnikxxx

                  91811027




                  91811027























                      1














                      This example doesn't make much sense in this context, because you're throwing the same exception and not doing anything else. Logging it at least will make much more sence. You're catching an exception to handle it or log it. If you cannot handle it, rethrow it (case 1) or wrap to something else (case 2).



                      Case 1:



                      public class Main {

                      // forced to handle or rethrow again
                      public static void main(String[] args) throws IOException {
                      read();
                      }

                      public static void read() throws IOException {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      throw e;
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      In the output you'll see something like:



                      Exception in thread "main" java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      at com.alex.java.Main.main(Main.java:14)
                      **Case 2:**


                      The pattern below allows you to change the type of the exception and keep the original exception details as well:



                      try {
                      // Some code here
                      } catch (IOException e) {
                      throw new IllegalStateException(e);
                      }


                      This case often happens when you would like to substitute a Checked Exception with an Unchecked exception preserving the origination of the issue and keep all the information (what called exception chaining).



                      Regular use-cases:




                      • You cannot handle a Checked Exception and you don't want to rethow it to the caller. Rethoring checked exceptions will force the caller to handle it. This is not what you want to do if there is no regular cases for recovery.

                      • Exceptions like IOException are rarely useful to the client. You need to send something more specific and clear in scope of you business domain.


                      IOException wrapped to Unchecked Exception like DocumentReadException will shed light on actual situation and will not force the callers to handle it:



                      public class Main {

                      public static void main(String[] args) {
                      read();
                      }

                      public static void read() {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      // log and wrap the exception to a specific business exception
                      logger.error("Error reading the document", e);
                      throw new DocumentReadException(e);
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      The output will be similar to:



                      Exception in thread "main" java.lang.IllegalArgumentException: Error reading the document
                      at com.alex.java.Main.read(Main.java:21)
                      at com.alex.java.Main.main(Main.java:14)
                      Caused by: java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      ... 1 more


                      As you can see from the stack-trace, the root cause was logger to help you find out the original problem and the business domain exception was sent to a user.






                      share|improve this answer


























                      • It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

                        – Corrodias
                        11 hours ago
















                      1














                      This example doesn't make much sense in this context, because you're throwing the same exception and not doing anything else. Logging it at least will make much more sence. You're catching an exception to handle it or log it. If you cannot handle it, rethrow it (case 1) or wrap to something else (case 2).



                      Case 1:



                      public class Main {

                      // forced to handle or rethrow again
                      public static void main(String[] args) throws IOException {
                      read();
                      }

                      public static void read() throws IOException {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      throw e;
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      In the output you'll see something like:



                      Exception in thread "main" java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      at com.alex.java.Main.main(Main.java:14)
                      **Case 2:**


                      The pattern below allows you to change the type of the exception and keep the original exception details as well:



                      try {
                      // Some code here
                      } catch (IOException e) {
                      throw new IllegalStateException(e);
                      }


                      This case often happens when you would like to substitute a Checked Exception with an Unchecked exception preserving the origination of the issue and keep all the information (what called exception chaining).



                      Regular use-cases:




                      • You cannot handle a Checked Exception and you don't want to rethow it to the caller. Rethoring checked exceptions will force the caller to handle it. This is not what you want to do if there is no regular cases for recovery.

                      • Exceptions like IOException are rarely useful to the client. You need to send something more specific and clear in scope of you business domain.


                      IOException wrapped to Unchecked Exception like DocumentReadException will shed light on actual situation and will not force the callers to handle it:



                      public class Main {

                      public static void main(String[] args) {
                      read();
                      }

                      public static void read() {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      // log and wrap the exception to a specific business exception
                      logger.error("Error reading the document", e);
                      throw new DocumentReadException(e);
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      The output will be similar to:



                      Exception in thread "main" java.lang.IllegalArgumentException: Error reading the document
                      at com.alex.java.Main.read(Main.java:21)
                      at com.alex.java.Main.main(Main.java:14)
                      Caused by: java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      ... 1 more


                      As you can see from the stack-trace, the root cause was logger to help you find out the original problem and the business domain exception was sent to a user.






                      share|improve this answer


























                      • It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

                        – Corrodias
                        11 hours ago














                      1












                      1








                      1







                      This example doesn't make much sense in this context, because you're throwing the same exception and not doing anything else. Logging it at least will make much more sence. You're catching an exception to handle it or log it. If you cannot handle it, rethrow it (case 1) or wrap to something else (case 2).



                      Case 1:



                      public class Main {

                      // forced to handle or rethrow again
                      public static void main(String[] args) throws IOException {
                      read();
                      }

                      public static void read() throws IOException {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      throw e;
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      In the output you'll see something like:



                      Exception in thread "main" java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      at com.alex.java.Main.main(Main.java:14)
                      **Case 2:**


                      The pattern below allows you to change the type of the exception and keep the original exception details as well:



                      try {
                      // Some code here
                      } catch (IOException e) {
                      throw new IllegalStateException(e);
                      }


                      This case often happens when you would like to substitute a Checked Exception with an Unchecked exception preserving the origination of the issue and keep all the information (what called exception chaining).



                      Regular use-cases:




                      • You cannot handle a Checked Exception and you don't want to rethow it to the caller. Rethoring checked exceptions will force the caller to handle it. This is not what you want to do if there is no regular cases for recovery.

                      • Exceptions like IOException are rarely useful to the client. You need to send something more specific and clear in scope of you business domain.


                      IOException wrapped to Unchecked Exception like DocumentReadException will shed light on actual situation and will not force the callers to handle it:



                      public class Main {

                      public static void main(String[] args) {
                      read();
                      }

                      public static void read() {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      // log and wrap the exception to a specific business exception
                      logger.error("Error reading the document", e);
                      throw new DocumentReadException(e);
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      The output will be similar to:



                      Exception in thread "main" java.lang.IllegalArgumentException: Error reading the document
                      at com.alex.java.Main.read(Main.java:21)
                      at com.alex.java.Main.main(Main.java:14)
                      Caused by: java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      ... 1 more


                      As you can see from the stack-trace, the root cause was logger to help you find out the original problem and the business domain exception was sent to a user.






                      share|improve this answer















                      This example doesn't make much sense in this context, because you're throwing the same exception and not doing anything else. Logging it at least will make much more sence. You're catching an exception to handle it or log it. If you cannot handle it, rethrow it (case 1) or wrap to something else (case 2).



                      Case 1:



                      public class Main {

                      // forced to handle or rethrow again
                      public static void main(String[] args) throws IOException {
                      read();
                      }

                      public static void read() throws IOException {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      throw e;
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      In the output you'll see something like:



                      Exception in thread "main" java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      at com.alex.java.Main.main(Main.java:14)
                      **Case 2:**


                      The pattern below allows you to change the type of the exception and keep the original exception details as well:



                      try {
                      // Some code here
                      } catch (IOException e) {
                      throw new IllegalStateException(e);
                      }


                      This case often happens when you would like to substitute a Checked Exception with an Unchecked exception preserving the origination of the issue and keep all the information (what called exception chaining).



                      Regular use-cases:




                      • You cannot handle a Checked Exception and you don't want to rethow it to the caller. Rethoring checked exceptions will force the caller to handle it. This is not what you want to do if there is no regular cases for recovery.

                      • Exceptions like IOException are rarely useful to the client. You need to send something more specific and clear in scope of you business domain.


                      IOException wrapped to Unchecked Exception like DocumentReadException will shed light on actual situation and will not force the callers to handle it:



                      public class Main {

                      public static void main(String[] args) {
                      read();
                      }

                      public static void read() {
                      try {
                      readInternal();
                      } catch (IOException e) {
                      // log and wrap the exception to a specific business exception
                      logger.error("Error reading the document", e);
                      throw new DocumentReadException(e);
                      }
                      }

                      private static void readInternal() throws IOException {
                      throw new IOException("Output error");
                      }
                      }


                      The output will be similar to:



                      Exception in thread "main" java.lang.IllegalArgumentException: Error reading the document
                      at com.alex.java.Main.read(Main.java:21)
                      at com.alex.java.Main.main(Main.java:14)
                      Caused by: java.io.IOException: Output error
                      at com.alex.java.Main.readInternal(Main.java:26)
                      at com.alex.java.Main.read(Main.java:19)
                      ... 1 more


                      As you can see from the stack-trace, the root cause was logger to help you find out the original problem and the business domain exception was sent to a user.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 6 hours ago

























                      answered 19 hours ago









                      J-AlexJ-Alex

                      4,37562743




                      4,37562743













                      • It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

                        – Corrodias
                        11 hours ago



















                      • It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

                        – Corrodias
                        11 hours ago

















                      It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

                      – Corrodias
                      11 hours ago





                      It does make sense to throw a new exception of the same kind if you either want a new stack trace or want to add an informative message.

                      – Corrodias
                      11 hours ago


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54982437%2fwhat-is-the-difference-between-throw-e-and-throw-new-exceptione%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Why does my Macbook overheat and use so much CPU and energy when on YouTube?Why do so many insist on using...

                      How to prevent page numbers from appearing on glossaries?How to remove a dot and a page number in the...

                      Puerta de Hutt Referencias Enlaces externos Menú de navegación15°58′00″S 5°42′00″O /...