http://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&feed=atom&action=historyAPIDesignPatterns:Exceptions - Revision history2024-03-28T21:24:20ZRevision history for this page on the wikiMediaWiki 1.12.0rc1http://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=4677&oldid=prevJaroslavTulach: /* Runtime vs. Checked */2011-03-23T10:49:52Z<p><span class="autocomment">Runtime vs. Checked</span></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 10:49, 23 March 2011</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 33:</td>
<td colspan="2" class="diff-lineno">Line 33:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Runtime vs. Checked ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Runtime vs. Checked ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>[[Java]] is the first industrial language that introduced [[<del style="color: red; font-weight: bold; text-decoration: none;">wikipedia::Checked_exception|checked exceptions</del>]]. As such, when talking about exceptions in context of [[Java]], one cannot escape from talking about runtime vs. checked benefits and drawbacks. However this is tricky, as far as I know this is a perfect topic to start never-ending flamewar. Even the [[wikipedia::Checked_exception|wikipedia]]'s article related to pros and cons is written very defensively (some say.., others mean..., etc.), so it seems important to approach the topic carefully.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>[[Java]] is the first industrial language that introduced [[<ins style="color: red; font-weight: bold; text-decoration: none;">Checked exception</ins>]]<ins style="color: red; font-weight: bold; text-decoration: none;">s</ins>. As such, when talking about exceptions in context of [[Java]], one cannot escape from talking about runtime vs. checked benefits and drawbacks. However this is tricky, as far as I know this is a perfect topic to start never-ending flamewar. Even the [[wikipedia::Checked_exception|wikipedia]]'s article related to pros and cons is written very defensively (some say.., others mean..., etc.), so it seems important to approach the topic carefully.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>There may differences between checked and unchecked exception in comprehensibility, readability or maintainability of the code written against libraries using the first or the latter. However as I argued in [[Runtime_Aspects_of_APIs|Chapter 11]], Runtime Aspects of APIs, from the point of view of API evolution, there is no difference. When a method in a library is written so it can throw some exception in one version and in some newer version decides to throw yet another exception type under some circumstances, then this is an incompatible change. And the change is incompatible in both cases. When using checked exceptions, the change is source incompatible, as one needs to change the signature of the method to define the new exception. As a result code that was compilable, may get broken. In the case of unchecked exceptions, the change is functionally incompatible - as the code which originally caught all exceptions thrown from the method, will no longer work as expected. As such the difference between runtime and checked for API design is not as big as it might have seen.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>There may differences between checked and unchecked exception in comprehensibility, readability or maintainability of the code written against libraries using the first or the latter. However as I argued in [[Runtime_Aspects_of_APIs|Chapter 11]], Runtime Aspects of APIs, from the point of view of API evolution, there is no difference. When a method in a library is written so it can throw some exception in one version and in some newer version decides to throw yet another exception type under some circumstances, then this is an incompatible change. And the change is incompatible in both cases. When using checked exceptions, the change is source incompatible, as one needs to change the signature of the method to define the new exception. As a result code that was compilable, may get broken. In the case of unchecked exceptions, the change is functionally incompatible - as the code which originally caught all exceptions thrown from the method, will no longer work as expected. As such the difference between runtime and checked for API design is not as big as it might have seen.</div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=3689&oldid=prevJaroslavTulach: /* Deciding on Importance */2010-05-07T07:54:52Z<p><span class="autocomment">Deciding on Importance</span></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 07:54, 7 May 2010</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 67:</td>
<td colspan="2" class="diff-lineno">Line 67:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>When dealing with flow of exceptions in a complex, modular system, one needs to solve an important problem: ''decide whether an exception is important or not''. This may sound easy, but when you get an exception from a library, how can you tell whether this is something that shall be shown to the user as an information about failed I/O or whether this is an unexpected error state that needs to be logged and workarounded somehow? This is tough. Usual solution builds on the assumption that the top most caller knows the scope of an action (like ''I want to save a file'', ''I want to compile'', etc.) and this top most caller will decide on the importance. This is easy to understand model, and it works well in most situations (especially if there are no exceptional states), however in [[NetBeans]] we needed more granular identification. As such we created a model of annotating an exception with additional attributes:</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>When dealing with flow of exceptions in a complex, <ins style="color: red; font-weight: bold; text-decoration: none;">[[</ins>modular system<ins style="color: red; font-weight: bold; text-decoration: none;">]]</ins>, one needs to solve an important problem: ''decide whether an exception is important or not''. This may sound easy, but when you get an exception from a library, how can you tell whether this is something that shall be shown to the user as an information about failed I/O or whether this is an unexpected error state that needs to be logged and workarounded somehow? This is tough. Usual solution builds on the assumption that the top most caller knows the scope of an action (like ''I want to save a file'', ''I want to compile'', etc.) and this top most caller will decide on the importance. This is easy to understand model, and it works well in most situations (especially if there are no exceptional states), however in [[NetBeans]] we needed more granular identification. As such we created a model of annotating an exception with additional attributes:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1680&oldid=prevJaroslavTulach at 12:41, 15 November 20082008-11-15T12:41:02Z<p></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 12:41, 15 November 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 88:</td>
<td colspan="2" class="diff-lineno">Line 88:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>Exceptions are [[APIDesignPatterns:ExceptionExtensibility|easily extensible]] via subclassing.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>Exceptions are [[APIDesignPatterns:ExceptionExtensibility|easily extensible]] via subclassing.</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">[[Category:APIDesignPatterns]]</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">[[Category:APIDesignPatterns:Exceptions]]</ins></div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1625&oldid=prevJaroslavTulach at 18:14, 8 November 20082008-11-08T18:14:27Z<p></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 18:14, 8 November 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 87:</td>
<td colspan="2" class="diff-lineno">Line 87:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">It has been mentioned that changing a code to throw a new exception is not compatible change. However this is not fully true, because [[Java]] exceptions </del>are <del style="color: red; font-weight: bold; text-decoration: none;">regular classes, and classes support inheritance, one can define new subtypes of existing exceptions and yet keep the code written by your API users compatible. Imagine there is a method in version one throwing ordinary I/O exception:</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">Exceptions </ins>are [[<ins style="color: red; font-weight: bold; text-decoration: none;">APIDesignPatterns</ins>:<ins style="color: red; font-weight: bold; text-decoration: none;">ExceptionExtensibility</ins>|<ins style="color: red; font-weight: bold; text-decoration: none;">easily extensible</ins>]] <ins style="color: red; font-weight: bold; text-decoration: none;">via subclassing</ins>.</div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">public static int compute(int x, int y) throws IOException {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> if (y - x == 1) throw new IOException("For some reason I cannot deal with this!");</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> return x + y;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">}</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"></source></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">Now people can use this method to do many things, complex ones or trivial like to sum two numbers:</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">int result;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">try {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> result = compute(1, 2);</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">} catch (IOException ex) {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> Logger.getLogger("mylogger").log(Level.WARNING, "Problem!", ex);</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> result = -1;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">}</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"></source></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">This is a valid use of the compute API method. As authors of the library, we value our users and want to support this API use in future. However we also want to please more and more users. If some other ones require us to provide better information about the values of '''x''' and '''y''', instead of just throwing the '''IOException''', can we help them? Can we change the contract and yet pretend we have not changed anything? Yes, this is possible, just imagine version two of the library:</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">public static int compute(int x, int y) throws IOException {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> if (y - x == 1) throw new StrangeXYException(x, y);</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> return x + y;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">}</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">public final class StrangeXYException extends IOException {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> int x, y;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> StrangeXYException(int x, int y) {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> super("For some reason I cannot deal with this!");</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> this.x = x;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> this.y = y;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> }</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> public int getX() { return x; }</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> public int getY() { return y; }</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">}</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"></source></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">The previously written client code remains valid. A subclass of '''IOException''' is thrown, it is matched by the '''catch (IOException ex)''' block and everything continues to work as it used to. Yet, if one is interested in more detailed information about the failure, one can catch the version two newly defined exception:</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">int result;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">try {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> result = compute(1, 2);</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">} catch (StrangeXYException ex) {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> // compute ourselves meaningful result</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> result = ex.getX() + ex.getY();</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">} catch (IOException ex) {</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> Logger.getLogger("mylogger").log(Level.WARNING, "Problem!", ex);</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"> result = -1;</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">}</del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"></source></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">The object oriented nature of '''try/catch''' statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than for example the one available with </del>[[<del style="color: red; font-weight: bold; text-decoration: none;">Talk</del>:<del style="color: red; font-weight: bold; text-decoration: none;">Blogs:AndreiBadea:EnumsInAPIs#Joel_Neely_said_...</del>|<del style="color: red; font-weight: bold; text-decoration: none;">switch/case</del>]] <del style="color: red; font-weight: bold; text-decoration: none;">where inheritance is not taken into account at all</del>.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;"><comments/></del></div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div></div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1365&oldid=prevJaroslavTulach at 21:38, 14 September 20082008-09-14T21:38:29Z<p></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 21:38, 14 September 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 145:</td>
<td colspan="2" class="diff-lineno">Line 145:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>The object oriented nature of '''try/catch''' statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than for example the one available with [[Talk:Blogs:AndreiBadea:EnumsInAPIs#Joel_Neely_said_...|switch/case]] where inheritance is not taken into account at all.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>The object oriented nature of '''try/catch''' statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than for example the one available with [[Talk:Blogs:AndreiBadea:EnumsInAPIs#Joel_Neely_said_...|switch/case]] where inheritance is not taken into account at all.</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><comments/></ins></div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1363&oldid=prevJaroslavTulach at 21:32, 14 September 20082008-09-14T21:32:48Z<p></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 21:32, 14 September 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 144:</td>
<td colspan="2" class="diff-lineno">Line 144:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>The object oriented nature of <del style="color: red; font-weight: bold; text-decoration: none;">[[Talk:Blogs:AndreiBadea:EnumsInAPIs#Joel_Neely_said_...|</del>try/catch<del style="color: red; font-weight: bold; text-decoration: none;">]] </del>statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than for example the one available with <del style="color: red; font-weight: bold; text-decoration: none;">'''</del>switch/case<del style="color: red; font-weight: bold; text-decoration: none;">''' </del>where inheritance is not taken into account at all.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>The object oriented nature of <ins style="color: red; font-weight: bold; text-decoration: none;">'''</ins>try/catch<ins style="color: red; font-weight: bold; text-decoration: none;">''' </ins>statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than for example the one available with <ins style="color: red; font-weight: bold; text-decoration: none;">[[Talk:Blogs:AndreiBadea:EnumsInAPIs#Joel_Neely_said_...|</ins>switch/case<ins style="color: red; font-weight: bold; text-decoration: none;">]] </ins>where inheritance is not taken into account at all.</div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1362&oldid=prevJaroslavTulach at 21:31, 14 September 20082008-09-14T21:31:37Z<p></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 21:31, 14 September 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">TBD: just being created as a response to query by </del>Casper Bang:</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>Casper Bang <ins style="color: red; font-weight: bold; text-decoration: none;">asked following question after reading the [[TheAPIBook]]</ins>:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>''I was curious as to know how come, in a book strictly about API design in Java, you do not mention exceptions (particular checked exceptions) and the role they play in documenting assertions vs. hampering versionability. Did you simply think this to be too controversial an issue I wonder?''</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>''I was curious as to know how come, in a book strictly about API design in Java, you do not mention exceptions (particular checked exceptions) and the role they play in documenting assertions vs. hampering versionability. Did you simply think this to be too controversial an issue I wonder?''</div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 7:</td>
<td colspan="2" class="diff-lineno">Line 7:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Nothing special ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Nothing special ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>One reason why there is no special attention paid to <del style="color: red; font-weight: bold; text-decoration: none;">exception </del>is that at the end, exceptions are just classes. As such the same rules that can be applied to any class that shows up in the API can be applied to exceptions in the API as well. When adding exceptions in your API you will not do anything bad if you follow the ''do not expose more than necessary'' credo of [[Do_Not_Expose_More_Than_You_Want|Chapter 5]]. If your exception is supposed to be thrown just by your code, it is quite OK to make its constructor package private. That will guarantee the intended purpose of the exception, which is, to be thrown only by you and caught by clients of your API. It will guarantee that nobody can misuse and misinterpret this intention. From the opposite point of view: if you want your clients to throw an exception and only your code to consume it, you do not need public getters to get values passed into the constructor at the time the exception is thrown.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>One reason why there is no special attention paid to <ins style="color: red; font-weight: bold; text-decoration: none;">exceptions </ins>is that at the end, exceptions are just classes. As such the same rules that can be applied to any class that shows up in the API can be applied to exceptions in the API as well. When adding exceptions in your API you will not do anything bad if you follow the ''do not expose more than necessary'' credo of [[Do_Not_Expose_More_Than_You_Want|Chapter 5]]. If your exception is supposed to be thrown just by your code, it is quite OK to make its constructor package private. That will guarantee the intended purpose of the exception, which is, to be thrown only by you and caught by clients of your API. It will guarantee that nobody can misuse and misinterpret this intention. From the opposite point of view: if you want your clients to throw an exception and only your code to consume it, you do not need public getters to get values passed into the constructor at the time the exception is thrown.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>On the other hand, [[Do_Not_Expose_More_Than_You_Want|Chapter 5]] also advices to prefer factory methods over exposing constructors. I tried that few times, but I have a feeling that this feels a bit unnatural and as such I cannot recommend code like:</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>On the other hand, [[Do_Not_Expose_More_Than_You_Want|Chapter 5]] also advices to prefer factory methods over exposing constructors. I tried that few times, but I have a feeling that this feels a bit unnatural and as such I cannot recommend code like:</div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 29:</td>
<td colspan="2" class="diff-lineno">Line 29:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>The common mindshare among Java developers seems to expect that exceptions are raised by writing '''throw new Something''' and it is therefore likely better to expose constructor of your exception class instead of factory method. Still, if you do not expect people to benefit from subclassing your exception, make it '''final''' - your options for [[Ever_Changing_Targets|future evolution]] will remain more open.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>The common mindshare among Java developers seems to expect that exceptions are raised by writing '''throw new Something''' and it is therefore likely better to expose constructor of your exception class instead of factory method. Still, if you do not expect people to benefit from subclassing your exception, make it '''final''' - your options for [[Ever_Changing_Targets|future evolution]] will remain more open.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>In short, exceptions are classes. They shall follow the evolution rules applicable to classes, as discussed in [[Code_Against_Interfaces%2C_Not_Implementations|Chapter 6]]. It is not wise to add abstract methods into exceptions could have been subclassed in prior versions, it is not wise to expose fields, remove elements already available, etc. However Casper is right, this is not all that can be said about exceptions, it seems <del style="color: red; font-weight: bold; text-decoration: none;">there is </del>something special <del style="color: red; font-weight: bold; text-decoration: none;">at the end</del>.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>In short, exceptions are classes. They shall follow the evolution rules applicable to classes, as discussed in [[Code_Against_Interfaces%2C_Not_Implementations|Chapter 6]]. It is not wise to add abstract methods into exceptions <ins style="color: red; font-weight: bold; text-decoration: none;">that </ins>could have been subclassed in prior versions, it is not wise to expose fields, remove elements already available, etc. However Casper is right, this is not all that can be said about exceptions, it seems <ins style="color: red; font-weight: bold; text-decoration: none;">that </ins>something special <ins style="color: red; font-weight: bold; text-decoration: none;">remains unsaid</ins>.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Runtime vs. Checked ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Runtime vs. Checked ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>[[Java]] is the first industrial language that introduced [[wikipedia::Checked_exception|checked exceptions]]. As such, when talking about exceptions in context of [[Java]], one cannot escape from talking about runtime vs. checked. However this is tricky, as far as I know this is a perfect topic to start never-ending flamewar. Even the [[wikipedia::Checked_exception|wikipedia]]'s article related to pros and cons is written very defensively (some say.., others mean..., etc.), so it seems important to approach the topic carefully.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>[[Java]] is the first industrial language that introduced [[wikipedia::Checked_exception|checked exceptions]]. As such, when talking about exceptions in context of [[Java]], one cannot escape from talking about runtime vs. checked <ins style="color: red; font-weight: bold; text-decoration: none;">benefits and drawbacks</ins>. However this is tricky, as far as I know this is a perfect topic to start never-ending flamewar. Even the [[wikipedia::Checked_exception|wikipedia]]'s article related to pros and cons is written very defensively (some say.., others mean..., etc.), so it seems important to approach the topic carefully.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>There may differences between checked and unchecked exception in comprehensibility, readability or maintainability of the code written against libraries using the first or the latter. However as I argued in [[Runtime_Aspects_of_APIs|Chapter 11]], Runtime Aspects of APIs, from the point of view of API evolution, there is no difference. <del style="color: red; font-weight: bold; text-decoration: none;">If </del>a method in a library can throw some exception in one version and in some newer version decides to throw yet another exception type under some circumstances, then this is incompatible change. And the change is incompatible in both cases. When using checked exceptions, the change is <del style="color: red; font-weight: bold; text-decoration: none;">binary </del>incompatible, as one needs to change the signature of the method to define the new exception. In case of unchecked exceptions, the change is functionally incompatible - as the code which originally caught all exceptions thrown from the method, will no longer work as expected. As such the difference between runtime and checked for API design is not as big as it might have seen.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>There may differences between checked and unchecked exception in comprehensibility, readability or maintainability of the code written against libraries using the first or the latter. However as I argued in [[Runtime_Aspects_of_APIs|Chapter 11]], Runtime Aspects of APIs, from the point of view of API evolution, there is no difference. <ins style="color: red; font-weight: bold; text-decoration: none;">When </ins>a method in a library <ins style="color: red; font-weight: bold; text-decoration: none;">is written so it </ins>can throw some exception in one version and in some newer version decides to throw yet another exception type under some circumstances, then this is <ins style="color: red; font-weight: bold; text-decoration: none;">an </ins>incompatible change. And the change is incompatible in both cases. When using checked exceptions, the change is <ins style="color: red; font-weight: bold; text-decoration: none;">source </ins>incompatible, as one needs to change the signature of the method to define the new exception<ins style="color: red; font-weight: bold; text-decoration: none;">. As a result code that was compilable, may get broken</ins>. In <ins style="color: red; font-weight: bold; text-decoration: none;">the </ins>case of unchecked exceptions, the change is functionally incompatible - as the code which originally caught all exceptions thrown from the method, will no longer work as expected. As such the difference between runtime and checked for API design is not as big as it might have seen.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== My Single Exception ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== My Single Exception ==</div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 42:</td>
<td colspan="2" class="diff-lineno">Line 42:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">try {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> // do some operations</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>} catch (IOException ex) {</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>} catch (IOException ex) {</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div> throw new BuildException(oldEx);</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div> throw new BuildException(oldEx);</div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 47:</td>
<td colspan="2" class="diff-lineno">Line 49:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>This is <del style="color: red; font-weight: bold; text-decoration: none;">quite irritating verbosity</del>, if we keep in mind that almost every task needs to deal with I/O. Also the final error reports are not really easy to read - for one I/O failure, there are two exceptions chained to each other. Moreover only the inner one is important, the other is quite useless. Things can get even messier when you imagine that some maven goals are wrappers around Ant tasks. As such one gets chain of at least three exceptions, as maven goal needs to wrap the Ant's task invocation and the tasks wraps the I/O.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>This is <ins style="color: red; font-weight: bold; text-decoration: none;">overcomingly verbose</ins>, <ins style="color: red; font-weight: bold; text-decoration: none;">especially </ins>if we keep in mind that almost every task needs to deal with I/O. Also the final error reports are not really easy to read - for one I/O failure, there are two exceptions chained to each other. Moreover only the inner one is important, the other is quite useless. Things can get even messier when you imagine that some maven goals are wrappers around Ant tasks. As such one gets chain of at least three exceptions, as maven goal needs to wrap the Ant's task invocation and the tasks wraps the I/O.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>It would be much simpler if both [[Ant]] and [[Maven]] designers admitted that it is natural to throw '''IOException''' from inside its tasks/goal implementations. Then there could be:</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>It would be much simpler if both [[Ant]] and [[Maven]] designers admitted that it is natural to throw '''IOException''' from inside its tasks/goal implementations. Then there could be:</div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 65:</td>
<td colspan="2" class="diff-lineno">Line 67:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>When dealing with flow of exceptions in a complex, modular system, one needs to solve an important problem: ''decide whether an exception is important or not''. This may sound easy, but when you get an exception from a library, how can you tell whether this is something that shall be shown to the user as an information about failed I/O or whether this is an unexpected error state that needs to be <del style="color: red; font-weight: bold; text-decoration: none;">just </del>logged? This is tough. Usual solution <del style="color: red; font-weight: bold; text-decoration: none;">counts </del>that the top most caller knows the scope of an action (like ''I want to save a file'', ''I want to compile'', etc.) and this top most caller will decide on the importance. This is easy to understand model, and it works well in most situations (especially if there are no exceptional states), however in [[NetBeans]] we needed more granular identification. As such we created a model of annotating an exception with additional attributes:</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>When dealing with flow of exceptions in a complex, modular system, one needs to solve an important problem: ''decide whether an exception is important or not''. This may sound easy, but when you get an exception from a library, how can you tell whether this is something that shall be shown to the user as an information about failed I/O or whether this is an unexpected error state that needs to be logged <ins style="color: red; font-weight: bold; text-decoration: none;">and workarounded somehow</ins>? This is tough. Usual solution <ins style="color: red; font-weight: bold; text-decoration: none;">builds on the assumption </ins>that the top most caller knows the scope of an action (like ''I want to save a file'', ''I want to compile'', etc.) and this top most caller will decide on the importance. This is easy to understand model, and it works well in most situations (especially if there are no exceptional states), however in [[NetBeans]] we needed more granular identification. As such we created a model of annotating an exception with additional attributes:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 85:</td>
<td colspan="2" class="diff-lineno">Line 87:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>It has been mentioned that changing a code to throw a new exception is not compatible change. However this is not fully true, because [[Java]] exceptions are regular classes, and classes support inheritance, one can define new subtypes of existing exceptions and yet the code <del style="color: red; font-weight: bold; text-decoration: none;">remains </del>compatible. Imagine there is a method in version one throwing ordinary I/O exception:</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>It has been mentioned that changing a code to throw a new exception is not compatible change. However this is not fully true, because [[Java]] exceptions are regular classes, and classes support inheritance, one can define new subtypes of existing exceptions and yet <ins style="color: red; font-weight: bold; text-decoration: none;">keep </ins>the code <ins style="color: red; font-weight: bold; text-decoration: none;">written by your API users </ins>compatible. Imagine there is a method in version one throwing ordinary I/O exception:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 94:</td>
<td colspan="2" class="diff-lineno">Line 96:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>Now people can use this method to sum two numbers:</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>Now people can use this method <ins style="color: red; font-weight: bold; text-decoration: none;">to do many things, complex ones or trivial like </ins>to sum two numbers:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 106:</td>
<td colspan="2" class="diff-lineno">Line 108:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>This is a valid use of the compute API method. As authors of the library, we value our users and want to support this API use in future. However some other <del style="color: red; font-weight: bold; text-decoration: none;">users </del>require us to provide better information about the values of '''x''' and '''y''', instead of just throwing the '''IOException'''<del style="color: red; font-weight: bold; text-decoration: none;">. </del>Can we change the contract and yet pretend we have not changed anything? Yes, <del style="color: red; font-weight: bold; text-decoration: none;">that </del>is possible, imagine version two of the library:</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>This is a valid use of the compute API method. As authors of the library, we value our users and want to support this API use in future. However <ins style="color: red; font-weight: bold; text-decoration: none;">we also want to please more and more users. If </ins>some other <ins style="color: red; font-weight: bold; text-decoration: none;">ones </ins>require us to provide better information about the values of '''x''' and '''y''', instead of just throwing the '''IOException'''<ins style="color: red; font-weight: bold; text-decoration: none;">, can we help them? </ins>Can we change the contract and yet pretend we have not changed anything? Yes, <ins style="color: red; font-weight: bold; text-decoration: none;">this </ins>is possible, <ins style="color: red; font-weight: bold; text-decoration: none;">just </ins>imagine version two of the library:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><source lang="java"></div></td></tr>
<tr><td colspan="2" class="diff-lineno">Line 142:</td>
<td colspan="2" class="diff-lineno">Line 144:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></source></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>The object oriented nature of <del style="color: red; font-weight: bold; text-decoration: none;">'''</del>try/catch<del style="color: red; font-weight: bold; text-decoration: none;">''' </del>statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than the one available with '''switch/case''' where inheritance is not taken into account at all.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>The object oriented nature of <ins style="color: red; font-weight: bold; text-decoration: none;">[[Talk:Blogs:AndreiBadea:EnumsInAPIs#Joel_Neely_said_...|</ins>try/catch<ins style="color: red; font-weight: bold; text-decoration: none;">]] </ins>statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than <ins style="color: red; font-weight: bold; text-decoration: none;">for example </ins>the one available with '''switch/case''' where inheritance is not taken into account at all.</div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1361&oldid=prevJaroslavTulach: /* Extensibility */2008-09-14T21:13:18Z<p><span class="autocomment">Extensibility</span></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 21:13, 14 September 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 85:</td>
<td colspan="2" class="diff-lineno">Line 85:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">TBD</del>: <del style="color: red; font-weight: bold; text-decoration: none;">Subclassing</del>. <del style="color: red; font-weight: bold; text-decoration: none;">Compare </del>with switch/case</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">It has been mentioned that changing a code to throw a new exception is not compatible change. However this is not fully true, because [[Java]] exceptions are regular classes, and classes support inheritance, one can define new subtypes of existing exceptions and yet the code remains compatible. Imagine there is a method in version one throwing ordinary I/O exception</ins>:</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">public static int compute(int x, int y) throws IOException {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> if (y - x == 1) throw new IOException("For some reason I cannot deal with this!");</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> return x + y;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></source></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">Now people can use this method to sum two numbers:</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">int result;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">try {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> result = compute(1, 2);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">} catch (IOException ex) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> Logger</ins>.<ins style="color: red; font-weight: bold; text-decoration: none;">getLogger("mylogger").log(Level.WARNING, "Problem!", ex);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> result = -1;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></source></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">This is a valid use of the compute API method. As authors of the library, we value our users and want to support this API use in future. However some other users require us to provide better information about the values of '''x''' and '''y''', instead of just throwing the '''IOException'''. Can we change the contract and yet pretend we have not changed anything? Yes, that is possible, imagine version two of the library:</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">public static int compute(int x, int y) throws IOException {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> if (y - x == 1) throw new StrangeXYException(x, y);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> return x + y;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">public final class StrangeXYException extends IOException {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> int x, y;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> StrangeXYException(int x, int y) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> super("For some reason I cannot deal </ins>with <ins style="color: red; font-weight: bold; text-decoration: none;">this!");</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> this.x = x;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> this.y = y;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public int getX() { return x; }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public int getY() { return y; }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></source></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">The previously written client code remains valid. A subclass of '''IOException''' is thrown, it is matched by the '''catch (IOException ex)''' block and everything continues to work as it used to. Yet, if one is interested in more detailed information about the failure, one can catch the version two newly defined exception:</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">int result;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">try {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> result = compute(1, 2);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">} catch (StrangeXYException ex) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> // compute ourselves meaningful result</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> result = ex.getX() + ex.getY();</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">} catch (IOException ex) {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> Logger.getLogger("mylogger").log(Level.WARNING, "Problem!", ex);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> result = -1;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></source></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">The object oriented nature of '''try/catch''' statements makes evolution perfectly possible. With every new release one can define new specialized exception as subclass of some already existing one. The previously working code can remain unaffected, the new client code can extract the additional information from the new exception class exposed in the API. This is much more pleasant evolution than the one available with '''</ins>switch/case<ins style="color: red; font-weight: bold; text-decoration: none;">''' where inheritance is not taken into account at all.</ins></div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1360&oldid=prevJaroslavTulach: /* Deciding on Importance */2008-09-14T20:53:33Z<p><span class="autocomment">Deciding on Importance</span></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 20:53, 14 September 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 65:</td>
<td colspan="2" class="diff-lineno">Line 65:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del style="color: red; font-weight: bold; text-decoration: none;">TBD</del>: [[NetBeans]]' <del style="color: red; font-weight: bold; text-decoration: none;">ErrorManager </del>and <del style="color: red; font-weight: bold; text-decoration: none;">Exceptions classes</del>.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">When dealing with flow of exceptions in a complex, modular system, one needs to solve an important problem</ins>: <ins style="color: red; font-weight: bold; text-decoration: none;">''decide whether an exception is important or not''. This may sound easy, but when you get an exception from a library, how can you tell whether this is something that shall be shown to the user as an information about failed I/O or whether this is an unexpected error state that needs to be just logged? This is tough. Usual solution counts that the top most caller knows the scope of an action (like ''I want to save a file'', ''I want to compile'', etc.) and this top most caller will decide on the importance. This is easy to understand model, and it works well in most situations (especially if there are no exceptional states), however in </ins>[[NetBeans]] <ins style="color: red; font-weight: bold; text-decoration: none;">we needed more granular identification. As such we created a model of annotating an exception with additional attributes:</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">public final class Exceptions {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> private Exceptions() { }</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public static <T extends Throwable> T attachMessage(T ex, String msg);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public string <T extends Throwable> T attachLocalizedMessage(T ex, String msg);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public string <T extends Throwable> T attachImportance(T ex, java.util.Level level);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public static Level findImportance(Throwable t);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public static String findMessage(Throwable t);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public static String findLocalizedMessage(Throwable t);</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></source></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">More info at [http://bits.netbeans.org/6.1/javadoc/org-openide-util/org/openide/util/doc-files/logging.html logging FAQ]. As a result any code on the exception thrown chain can jump in and mark the exception as important or unimportant and pass it on. The final </ins>'<ins style="color: red; font-weight: bold; text-decoration: none;">''catch''' block then gets the importance information </ins>and <ins style="color: red; font-weight: bold; text-decoration: none;">uses it decide whether show a dialog to the user, or ''swallow'' the exception</ins>.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Extensibility ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>TBD: Subclassing. Compare with switch/case</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>TBD: Subclassing. Compare with switch/case</div></td></tr>
</table>JaroslavTulachhttp://wiki.apidesign.org/index.php?title=APIDesignPatterns:Exceptions&diff=1359&oldid=prevJaroslavTulach: /* My Single Exception */2008-09-14T20:37:56Z<p><span class="autocomment">My Single Exception</span></p>
<table style="background-color: white; color:black;">
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr>
<td colspan='2' style="background-color: white; color:black;">←Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 20:37, 14 September 2008</td>
</tr>
<tr><td colspan="2" class="diff-lineno">Line 49:</td>
<td colspan="2" class="diff-lineno">Line 49:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>This is quite irritating verbosity, if we keep in mind that almost every task needs to deal with I/O. Also the final error reports are not really easy to read - for one I/O failure, there are two exceptions chained to each other. Moreover only the inner one is important, the other is quite useless. Things can get even messier when you imagine that some maven goals are wrappers around Ant tasks. As such one gets chain of at least three exceptions, as maven goal needs to wrap the Ant's task invocation and the tasks wraps the I/O.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>This is quite irritating verbosity, if we keep in mind that almost every task needs to deal with I/O. Also the final error reports are not really easy to read - for one I/O failure, there are two exceptions chained to each other. Moreover only the inner one is important, the other is quite useless. Things can get even messier when you imagine that some maven goals are wrappers around Ant tasks. As such one gets chain of at least three exceptions, as maven goal needs to wrap the Ant's task invocation and the tasks wraps the I/O.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>-</td><td style="background: #ffa; color:black; font-size: smaller;"><div>It would be much simpler if both [[Ant]] and [[Maven]] designers</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>It would be much simpler if both [[Ant]] and [[Maven]] designers <ins style="color: red; font-weight: bold; text-decoration: none;">admitted that it is natural to throw '''IOException''' from inside its tasks/goal implementations. Then there could be:</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"><source lang="java"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">public abstract class Task {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"> public abstract void execute() throws IOException;</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">public class BuildException extends IOException {</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></source></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">The code inside custom '''execute''' implementation could be shorter, as there would be no need for the '''try/catch''' of I/O operation exceptions, users would get no wrapped I/O exceptions and the expressiveness would remain the same, as the possibility to raise the '''BuildException''' would be kept.</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== Deciding on Importance ==</div></td></tr>
</table>JaroslavTulach