<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Stop Catching Exceptions!</title>
	<atom:link href="http://gen5.info/q/2008/07/31/stop-catching-exceptions/feed/" rel="self" type="application/rss+xml" />
	<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/</link>
	<description>Towards Intelligent Systems</description>
	<pubDate>Thu, 20 Nov 2008 15:02:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
		<item>
		<title>By: Generation 5 &#187; What do you do when you&#8217;ve caught an exception?</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-723</link>
		<dc:creator>Generation 5 &#187; What do you do when you&#8217;ve caught an exception?</dc:creator>
		<pubDate>Wed, 27 Aug 2008 15:19:06 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-723</guid>
		<description>[...] For the most part, the code inside DoUnitOfWork() and the functions it calls tries to throw exceptions upward rather than catch them. [...]</description>
		<content:encoded><![CDATA[<p>[...] For the most part, the code inside DoUnitOfWork() and the functions it calls tries to throw exceptions upward rather than catch them. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Houle</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-641</link>
		<dc:creator>Paul Houle</dc:creator>
		<pubDate>Fri, 15 Aug 2008 01:08:04 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-641</guid>
		<description>@Karl,

    I like that.  One of the strengths of exceptions is that they are objects that can be manipulated outside of the try-catch-finally system.  As you demonstrate,  exceptions can be caught and then stuffed into a data structure:  then they can be inspected later.  It's also possible to create an exception,  store it in a data structure,  and throw it at another point,  which is useful for fault injection.  Thanks for the example!</description>
		<content:encoded><![CDATA[<p>@Karl,</p>
<p>    I like that.  One of the strengths of exceptions is that they are objects that can be manipulated outside of the try-catch-finally system.  As you demonstrate,  exceptions can be caught and then stuffed into a data structure:  then they can be inspected later.  It&#8217;s also possible to create an exception,  store it in a data structure,  and throw it at another point,  which is useful for fault injection.  Thanks for the example!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Karl</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-639</link>
		<dc:creator>Karl</dc:creator>
		<pubDate>Thu, 14 Aug 2008 19:05:58 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-639</guid>
		<description>@real:  Let me show you how exceptions are used for expected situations in real business logic in an enterprise system:

public class BusinessRuleSet
{
	private Set rules = new HashSet();

	public void addRule(BusinessRule rule)
	{
		rules.add(rule);
	}

	public void addRules(BusinessRuleSet ruleSet)
	{
		this.rules.addAll(ruleSet.rules);
	}

	public void applyTo(int recordIndex, Object subject) throws BusinessRulesFailedException
	{
		BusinessRulesFailedException errors = new BusinessRulesFailedException();

		for ( Iterator iter = rules.iterator(); iter.hasNext(); )
		{
			try
			{
				((BusinessRule)iter.next()).applyTo(recordIndex, subject);
			}
			catch ( BusinessRuleException e )
			{
				errors.addError(e);
			}
		}

		if ( errors.hasErrors() )
		{
			throw errors;
		}
	}
}

This is called via the following mechanism:

public void create(Collection records) throws BusinessRulesFailedException
{
	// Preamble to test for user access and such.
	...

	int index = 0;
	for(SomeType record: records)
	{
		createRules.applyTo(index, record);
		index++;
	}

	// Call data layer to create the records.
	...
}


This has been simplified for clarity.
Business rule objects evaluate a subject to test a particular business rule.  If the object is in violation of that rule, it throws a BusinessRuleException.

The BusinessRuleSet object captures these exceptions and builds up a master BusinessRulesFailedException, which contains all of the rules that failed.

The BusinessRulesFailedException bubbles up out of the business layer, into the UI layer where the call to create() was made.

The UI catches this exception and then sifts through the individual exceptions contained within so that it can write out each error for each field in the data entry screen where a business error was triggered.

The exceptions themselves are unchecked (though declared).  It is up to the programmer to decide what he wants to do, and where.

And for good reason too, as checked exceptions make it difficult to elegantly build higher order constructs.
For example, as a result of checked exceptions, many middleware products have to declare "throws Exception" (or wrap it in another exception) since they have NO idea what could be thrown from underneath.  Now everything built on top of this has to declare "throws Exception" (or manually unwrap the middleware exception, which causes a big ugly mess of evaluation code just to figure out what happened).  How useful is that?
The programmer using the product, however, will likely know what kind of exceptions will be coming out of it (or at least the ones he cares to deal with), and can handle them at the appropriate place.</description>
		<content:encoded><![CDATA[<p>@real:  Let me show you how exceptions are used for expected situations in real business logic in an enterprise system:</p>
<p>public class BusinessRuleSet<br />
{<br />
	private Set rules = new HashSet();</p>
<p>	public void addRule(BusinessRule rule)<br />
	{<br />
		rules.add(rule);<br />
	}</p>
<p>	public void addRules(BusinessRuleSet ruleSet)<br />
	{<br />
		this.rules.addAll(ruleSet.rules);<br />
	}</p>
<p>	public void applyTo(int recordIndex, Object subject) throws BusinessRulesFailedException<br />
	{<br />
		BusinessRulesFailedException errors = new BusinessRulesFailedException();</p>
<p>		for ( Iterator iter = rules.iterator(); iter.hasNext(); )<br />
		{<br />
			try<br />
			{<br />
				((BusinessRule)iter.next()).applyTo(recordIndex, subject);<br />
			}<br />
			catch ( BusinessRuleException e )<br />
			{<br />
				errors.addError(e);<br />
			}<br />
		}</p>
<p>		if ( errors.hasErrors() )<br />
		{<br />
			throw errors;<br />
		}<br />
	}<br />
}</p>
<p>This is called via the following mechanism:</p>
<p>public void create(Collection records) throws BusinessRulesFailedException<br />
{<br />
	// Preamble to test for user access and such.<br />
	&#8230;</p>
<p>	int index = 0;<br />
	for(SomeType record: records)<br />
	{<br />
		createRules.applyTo(index, record);<br />
		index++;<br />
	}</p>
<p>	// Call data layer to create the records.<br />
	&#8230;<br />
}</p>
<p>This has been simplified for clarity.<br />
Business rule objects evaluate a subject to test a particular business rule.  If the object is in violation of that rule, it throws a BusinessRuleException.</p>
<p>The BusinessRuleSet object captures these exceptions and builds up a master BusinessRulesFailedException, which contains all of the rules that failed.</p>
<p>The BusinessRulesFailedException bubbles up out of the business layer, into the UI layer where the call to create() was made.</p>
<p>The UI catches this exception and then sifts through the individual exceptions contained within so that it can write out each error for each field in the data entry screen where a business error was triggered.</p>
<p>The exceptions themselves are unchecked (though declared).  It is up to the programmer to decide what he wants to do, and where.</p>
<p>And for good reason too, as checked exceptions make it difficult to elegantly build higher order constructs.<br />
For example, as a result of checked exceptions, many middleware products have to declare &#8220;throws Exception&#8221; (or wrap it in another exception) since they have NO idea what could be thrown from underneath.  Now everything built on top of this has to declare &#8220;throws Exception&#8221; (or manually unwrap the middleware exception, which causes a big ugly mess of evaluation code just to figure out what happened).  How useful is that?<br />
The programmer using the product, however, will likely know what kind of exceptions will be coming out of it (or at least the ones he cares to deal with), and can handle them at the appropriate place.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Houle</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-628</link>
		<dc:creator>Paul Houle</dc:creator>
		<pubDate>Tue, 12 Aug 2008 23:03:09 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-628</guid>
		<description>@Real,  I'd like a more specific explanation of what you call "Domain Logic."</description>
		<content:encoded><![CDATA[<p>@Real,  I&#8217;d like a more specific explanation of what you call &#8220;Domain Logic.&#8221;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: the real deal</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-627</link>
		<dc:creator>the real deal</dc:creator>
		<pubDate>Tue, 12 Aug 2008 22:56:50 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-627</guid>
		<description>Good article, but still kinda misses the real problem: abuse of exception syntax for domain logic. First comment (by 'Matt') addresses this to some extent.

The real tragedy of exceptions, checked or otherwise, is that a generation of programmers uses a convoluted syntactic construction for many situations that should be analysed, modeled, and handled as domain logic.

The web form in the article is an example: user data that does not 'fit' either format or value is not an exception situation, it is to be expected and handled explicitly.

There is absolutely nothing wrong with plain old return values and error codes. Exceptions should not be used for anything which could be anticipated in the domain logic of whatever layer or abstraction is currently applicable.

There are some legitimate situations where exceptions are the right way, but they are very very few indeed. It is only when the abstraction is broken: for example, device failure (not, emphatically not, network failure: if you're doing anything with sockets or networks you damn well better expect to program retry and link down logic).

Using exceptions for domain logic is mental laziness disguised as a 'modern' technique.</description>
		<content:encoded><![CDATA[<p>Good article, but still kinda misses the real problem: abuse of exception syntax for domain logic. First comment (by &#8216;Matt&#8217;) addresses this to some extent.</p>
<p>The real tragedy of exceptions, checked or otherwise, is that a generation of programmers uses a convoluted syntactic construction for many situations that should be analysed, modeled, and handled as domain logic.</p>
<p>The web form in the article is an example: user data that does not &#8216;fit&#8217; either format or value is not an exception situation, it is to be expected and handled explicitly.</p>
<p>There is absolutely nothing wrong with plain old return values and error codes. Exceptions should not be used for anything which could be anticipated in the domain logic of whatever layer or abstraction is currently applicable.</p>
<p>There are some legitimate situations where exceptions are the right way, but they are very very few indeed. It is only when the abstraction is broken: for example, device failure (not, emphatically not, network failure: if you&#8217;re doing anything with sockets or networks you damn well better expect to program retry and link down logic).</p>
<p>Using exceptions for domain logic is mental laziness disguised as a &#8216;modern&#8217; technique.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Houle</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-625</link>
		<dc:creator>Paul Houle</dc:creator>
		<pubDate>Tue, 12 Aug 2008 19:48:21 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-625</guid>
		<description>I'm sorry it took so long for me to reply to the excellent comments this post received -- this post received so much attention that it crashed my VPS,  so I spent the weekend setting up a new server.

@Matt's got an interesting point.  The Try-* pattern is appropriate for parsing text.  Error handling based on return values gets into trouble quickly,  however,  if the effect of an error needs to propagate back up the call stack.  I used the example I did because it was a simple example where catching an exception locally is appropriate -- it's not accidental that this coincides where cases where return values work.

@Kit has probably built bulk loaders that batch together groups of records into transactions for speed.  I've seen this increase the speed of batch loads by factors of ten or more -- that matters when loads take several hours!  What he suggests is a premature optimization for many people,  but necessary for large jobs.

I disagree with @Bob.  In many cases,  the right answer for many networking-based exceptions is to retry the "unit of work,"  often with a delay.  This is how e-mail delivery and large-scale webcrawlers work.

@Klosowski,  I think encapsulation is a useful idea,  but it's also a partial truth,  particularly when things go wrong.  A "SubsystemAFailed" exception ~could~ be designed to give the caller useful semantics about what to do (answers for the eight questions) but it usually doesn't.  Reusing system-defined exceptions "does no harm" by avoiding information loss.

@paan,  I think it's more complicated than the effect that a language feature has on a particular programmer,  but more the effect that a feature has on the ecosystem around a language.  In particular,  error handling is a place where local decisions have global consequences.  Even if you were an absolute master at using checked exceptions,  you'll (i) be calling code written by people who are bad at it,  and (ii) having your code called by people who are bad it.  Since your code will have to deal with other people's exceptions,  and will throw exceptions into other people's call stacks,  you can't escape from the problems checked exceptions create.</description>
		<content:encoded><![CDATA[<p>I&#8217;m sorry it took so long for me to reply to the excellent comments this post received &#8212; this post received so much attention that it crashed my VPS,  so I spent the weekend setting up a new server.</p>
<p>@Matt&#8217;s got an interesting point.  The Try-* pattern is appropriate for parsing text.  Error handling based on return values gets into trouble quickly,  however,  if the effect of an error needs to propagate back up the call stack.  I used the example I did because it was a simple example where catching an exception locally is appropriate &#8212; it&#8217;s not accidental that this coincides where cases where return values work.</p>
<p>@Kit has probably built bulk loaders that batch together groups of records into transactions for speed.  I&#8217;ve seen this increase the speed of batch loads by factors of ten or more &#8212; that matters when loads take several hours!  What he suggests is a premature optimization for many people,  but necessary for large jobs.</p>
<p>I disagree with @Bob.  In many cases,  the right answer for many networking-based exceptions is to retry the &#8220;unit of work,&#8221;  often with a delay.  This is how e-mail delivery and large-scale webcrawlers work.</p>
<p>@Klosowski,  I think encapsulation is a useful idea,  but it&#8217;s also a partial truth,  particularly when things go wrong.  A &#8220;SubsystemAFailed&#8221; exception ~could~ be designed to give the caller useful semantics about what to do (answers for the eight questions) but it usually doesn&#8217;t.  Reusing system-defined exceptions &#8220;does no harm&#8221; by avoiding information loss.</p>
<p>@paan,  I think it&#8217;s more complicated than the effect that a language feature has on a particular programmer,  but more the effect that a feature has on the ecosystem around a language.  In particular,  error handling is a place where local decisions have global consequences.  Even if you were an absolute master at using checked exceptions,  you&#8217;ll (i) be calling code written by people who are bad at it,  and (ii) having your code called by people who are bad it.  Since your code will have to deal with other people&#8217;s exceptions,  and will throw exceptions into other people&#8217;s call stacks,  you can&#8217;t escape from the problems checked exceptions create.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: paan</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-610</link>
		<dc:creator>paan</dc:creator>
		<pubDate>Fri, 08 Aug 2008 05:46:08 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-610</guid>
		<description>I don't know..  I might be totally wrong here but..
If "programmers often misuse the concept of checked exceptions"  , doesn't that mean that it is the programmer that should learn the concept of checked exception handling. 

And if the programmer is have a hard time with his project because his programming language is a language that uses checked exception then either a)the language of choice for the project is not really suitable for the project or b)the programmer is not suitable/capable for the project

It's like a php programmer that is complaining about the disadvantages of a loosely typed language.</description>
		<content:encoded><![CDATA[<p>I don&#8217;t know..  I might be totally wrong here but..<br />
If &#8220;programmers often misuse the concept of checked exceptions&#8221;  , doesn&#8217;t that mean that it is the programmer that should learn the concept of checked exception handling. </p>
<p>And if the programmer is have a hard time with his project because his programming language is a language that uses checked exception then either a)the language of choice for the project is not really suitable for the project or b)the programmer is not suitable/capable for the project</p>
<p>It&#8217;s like a php programmer that is complaining about the disadvantages of a loosely typed language.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Przemek Klosowski</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-609</link>
		<dc:creator>Przemek Klosowski</dc:creator>
		<pubDate>Thu, 07 Aug 2008 01:39:20 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-609</guid>
		<description>A module's encapsulation should include the exceptions it throws. In your argument about 'breaking the build', the problem is that the bottom-most module
breaks encapsulation by generating new "uncontracted' exceptions. 

A proper module should catch all exceptions in its own methods, and throw just the few (or one) exception, ModuleXyzzyBarfed. After all, if properly abstracted, it shouldn't matter what specifically happened in this specific implementation---all the higher-level modules need to know is that this module failed.</description>
		<content:encoded><![CDATA[<p>A module&#8217;s encapsulation should include the exceptions it throws. In your argument about &#8216;breaking the build&#8217;, the problem is that the bottom-most module<br />
breaks encapsulation by generating new &#8220;uncontracted&#8217; exceptions. </p>
<p>A proper module should catch all exceptions in its own methods, and throw just the few (or one) exception, ModuleXyzzyBarfed. After all, if properly abstracted, it shouldn&#8217;t matter what specifically happened in this specific implementation&#8212;all the higher-level modules need to know is that this module failed.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Wolter</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-608</link>
		<dc:creator>Wolter</dc:creator>
		<pubDate>Thu, 07 Aug 2008 00:48:15 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-608</guid>
		<description>@Bob:

No, all us "checked exceptions are bad" people believe it should be up to the programmer to decide when, where, and if he deals with a particular exception, and that he shouldn't be hindered with extra boilerplate by people who think it necessary to force awareness of a particular exception.

Unchecked exceptions can handle distributed system issues perfectly well.  This is irrelevant to the discussion.</description>
		<content:encoded><![CDATA[<p>@Bob:</p>
<p>No, all us &#8220;checked exceptions are bad&#8221; people believe it should be up to the programmer to decide when, where, and if he deals with a particular exception, and that he shouldn&#8217;t be hindered with extra boilerplate by people who think it necessary to force awareness of a particular exception.</p>
<p>Unchecked exceptions can handle distributed system issues perfectly well.  This is irrelevant to the discussion.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bob</title>
		<link>http://gen5.info/q/2008/07/31/stop-catching-exceptions/#comment-607</link>
		<dc:creator>Bob</dc:creator>
		<pubDate>Wed, 06 Aug 2008 23:02:00 +0000</pubDate>
		<guid isPermaLink="false">http://gen5.info/q/?p=43#comment-607</guid>
		<description>All you "checked exceptions are bad" people are like people who think distributed systems should behave just like local systems.  The network is always up right?  When it goes down we don't know what will happen!  

When there's a checked exception in an API it's basically saying that something is likely to go wrong here.  IOException happen when the disk fills up, SQLExceptions happen when the database goes down, etc.  Just because that doesn't happen most of the time doesn't mean your program should just merrilly pretend it couldn't happen and fail in an unexpected way when these conditions occur.</description>
		<content:encoded><![CDATA[<p>All you &#8220;checked exceptions are bad&#8221; people are like people who think distributed systems should behave just like local systems.  The network is always up right?  When it goes down we don&#8217;t know what will happen!  </p>
<p>When there&#8217;s a checked exception in an API it&#8217;s basically saying that something is likely to go wrong here.  IOException happen when the disk fills up, SQLExceptions happen when the database goes down, etc.  Just because that doesn&#8217;t happen most of the time doesn&#8217;t mean your program should just merrilly pretend it couldn&#8217;t happen and fail in an unexpected way when these conditions occur.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
