<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Basil Vandegriend: Professional Software Development &#187; error handling</title>
	<atom:link href="http://www.basilv.com/psd/blog/tag/error-handling/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.basilv.com/psd</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 13:23:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Errors Errors Everywhere</title>
		<link>http://www.basilv.com/psd/blog/2007/errors-errors-everywhere</link>
		<comments>http://www.basilv.com/psd/blog/2007/errors-errors-everywhere#comments</comments>
		<pubDate>Mon, 11 Jun 2007 14:22:30 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[maintenance]]></category>
		<category><![CDATA[defects]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2007/errors-errors-everywhere</guid>
		<description><![CDATA[If you are a software developer and have not maintained operational applications with real users hammering away at it, then you are missing some important lessons. You might not fully appreciate the operational challenges facing the maintenance and support team, particularly when the software in question is suffering in the areas of reliability, performance, or [...]]]></description>
			<content:encoded><![CDATA[<p>If you are a software developer and have not maintained operational applications with real users hammering away at it, then you are missing some important lessons. You might not fully appreciate the operational challenges facing the maintenance and support team, particularly when the software in question is suffering in the areas of reliability, performance, or capacity. Over my period of involvement with application maintenance, I have been amazed at the number of incidents and problems that arise when an application goes into production. That is why in the last few months I have written several articles about reliability such as <a href="http://www.basilv.com/psd/blog/2007/error-handling-and-reliability">Error Handling and Reliability</a>.  </p>
<p>Based on my experience, I thought I had a good appreciation for what can go wrong. That changed recently when I experienced a day filled with too many problems and errors to be believed. The day started off innocently enough until a member of the production support team came by to inform us that he had accidentally terminated the database connection of one of our batch jobs due to transposing two numbers in the identifier. This by fluke matched our job instead of the one he wanted. Okay, no problem, we simply need to confirm that nothing was corrupted and restart the process. We checked our email for the notification email that is sent when a batch job abnormally terminates in order to verify which job had been affected. No such email was found. A little puzzled, we checked the server and confirmed that the process was no longer running. But another batch process was executing, and we identified it as a subsequent batch job dependent on the first. Subsequent jobs only run if the predecessors execute successfully, so we had a sinking feeling as we started checking the log files. Sure enough, due to a complete lack of error handling, the first job had reported a successful execution despite the database connection failure, which had caused the second job to start. That explained the lack of a notification email. The second job depended on the processing results of the first job, so the output of the second job was suspect and likely wrong. We had to kill the second job. If the first job had just failed, we could have restarted it without a problem, but now we had to investigate how to undo the effects of both jobs and manually restart the first. </p>
<p>Well, that didn't seem too bad, until I had time to think for a second. That is when I realized that our batch jobs are always scheduled at night or the weekends, and never during business hours. What was one doing running during the day? That prompted another investigation, which revealed that the job does normally runs on weekends. But the previous weekend there were problems with predecessors to this job that caused it to be delayed until one of the nights during the week. So why didn't it run at night? We were surprised to discover that it had – it just didn't finish. Due to performance issues, the job had run for over eight hours, extending into the day, before it was killed by mistake.</p>
<p>By late afternoon of that day we had multiple investigations underway trying to track down the various <a href="http://www.basilv.com/psd/blog/2006/how-to-do-root-cause-analysis">root causes</a> of the problems we had identified. My mind reached the saturation point sometime in the afternoon, so I cannot remember the details concerning what was found. I suspect there were other problems unearthed that I have since forgotten. Nor where we able to get everything fixed that same day. That combination of problems, coming together on that one day, kept a surprising number of people busy for days sorting out the mess.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2007/errors-errors-everywhere/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Tale of Bad Exception Handling in Finally Blocks in Java</title>
		<link>http://www.basilv.com/psd/blog/2007/a-tale-of-bad-exception-handling-in-finally-blocks-in-java</link>
		<comments>http://www.basilv.com/psd/blog/2007/a-tale-of-bad-exception-handling-in-finally-blocks-in-java#comments</comments>
		<pubDate>Sun, 29 Apr 2007 15:27:33 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[coding standards]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2007/a-tale-of-bad-exception-handling-in-finally-blocks-in-java</guid>
		<description><![CDATA[There is always something more to learn. That was the lesson for me last week when I learned something new about the Java programming language, despite having used professionally it for almost 10 years. I was upgrading a Java web application to WebSphere server version 6.1 and as the first step I switched the development [...]]]></description>
			<content:encoded><![CDATA[<p>There is always something more to <a href="http://www.basilv.com/psd/blog/2006/perpetual-learning">learn</a>. That was the lesson for me last week when I learned something new about the Java programming language, despite having used professionally it for almost 10 years.</p>
<p>I was upgrading a Java web application to <a href="http://www.ibm.com/software/webservers/appserv/was/">WebSphere server</a> version 6.1 and as the first step I switched the development environment to <a href="http://www.ibm.com/software/awdtools/studioappdev/">Rational Application Developer</a> version 7. With the new <a href="http://en.wikipedia.org/wiki/Integrated_development_environment">IDE</a> came an improved compiler that reported additional warnings, so it didn't surprise me to see hundreds of new warnings. It is a standard practice of mine to eliminate warnings, even harmless ones, since a significant warning can easily be missed if harmless warnings are allowed to remain. As I worked my way through the warnings, I came across a new one I did not recognize: "<code>Finally block does not complete normally</code>". A simplified version of the code producing this warning is shown below:</p>
<pre class="prettyprint">
  boolean performBusinessOperation() {
    boolean operationResult = false;
    try {
      // Perform some business logic...
      operationResult = true;
    } catch (IllegalStateException e) {
      // Handle this exception..
      operationResult = false;
    } catch (IllegalArgumentException e) {
      // Handle this exception...
      operationResult = false;
    } finally {
      // Common cleanup...
      // Following line produces warning
      // "Finally block does not complete normally"
      return operationResult;
    }
  }</pre>
<p>This was not code I had written, so I spent some time trying to figure out the reason for the warning. In Java, the finally block is guaranteed to be executed after the contained try block finishes execution, even if an exception is thrown within the try block. If an exception is thrown and not caught within a function, the exception is propagated up the call stack until it encounters an appropriate catch block. But in this particular case within the <code>performBusinessOperation</code> method, if an uncaught exception is thrown, the finally block will run and perform the <code>return</code> statement. So which will win - the exception or the return? I was not sure, which in my mind explained the warning - it is bad practice to write code with unclear behavior. So I fixed the code by moving the return statement outside the finally block and moved on to the next warning.</p>
<p>Once I was finished eliminating warnings, I ran the entire suite of automated unit tests. To my surprise, I had a few failures. When I tracked down the offending code, I was surprised to see that it was my fix for the "<code>Finally block does not complete normally</code>" warning that broke the tests. How could that be? After further tracing and debugging, I finally found the reason: the unit test incorrectly invoked the method in question, causing it to throw a <code>NullPointerException</code> from within the try block. Having the return statement within the finally block apparently was causing the exception to be silently discarded. I found this shocking. This is dangerous behavior for a language, and I had problems believing that was actually the case. So I wrote a quick unit test for verification, shown below.</p>
<pre class="prettyprint">
public class ReturnInFinallyBlockExample
  extends junit.framework.TestCase
{
  @SuppressWarnings("finally")
  private boolean isReturnWithinFinally() {
    try {
      if (true) throw new RuntimeException();
    } finally {
      return true; // This hides the exception
    }
  }

  private boolean isReturnOutsideFinally() {
    try {
      if (true) throw new RuntimeException();
    } finally {
      // Return outside finally block.
    }
    return true;
  }

  public void testReturnFromFinallyBlockWithUnhandledException() {
    assertTrue(isReturnWithinFinally());
    try {
      isReturnOutsideFinally();
      fail("Expect exception");
    } catch (RuntimeException e) {
      // Expected case.
    }
  }
}</pre>
<p>This test case passes, demonstrating that the uncaught exception within the try block is silently discarded if the return statement is within the finally block. Note my use of the Java 5 annotation <code>@SuppressWarnings("finally")</code> in order to stop the compiler from reporting the "<code>Finally block does not complete normally</code>" warning for this example.</p>
<p>Perhaps I should have been less surprised by this behavior in Java given that I was already aware of another suboptimal situation regarding Java exception handling in finally blocks: if an uncaught exception is thrown in a try block and then another exception is thrown in the finally block, it will be the second exception that is propagated out of the method. The first exception will be silently lost. The following test case demonstrates this behavior:</p>
<pre class="prettyprint">
public class ExceptionInFinallyBlockExample
  extends junit.framework.TestCase
{
  private void haveExceptionInFinallyBlock() {
    try {
      if (true) throw new IllegalArgumentException();
    } finally {
      if (true) throw new NullPointerException();
    }
  }
  public void testHaveExceptionInFinallyBlock() {
    try {
      haveExceptionInFinallyBlock();
      fail("Expect exception");
    } catch (NullPointerException e) {
      // Expected case.
    }
  }
}</pre>
<p>Ignoring errors is dangerous, as I have discussed in my article on <a href="http://www.basilv.com/psd/blog/2007/error-handling-and-reliability">Error Handling and Reliability</a>. So I strongly feel that the Java language should have prohibited return statements in finally blocks. Fortunately, modern Java IDEs like <a href="http://www.eclipse.org/">Eclipse</a> can make up for this shortcoming by allowing you to flag this code construct as an error rather than a warning.</p>
<p>The source code listed in this article is provided in the <em>Java Examples</em> project which can be downloaded from the <a href="http://www.basilv.com/psd/software">Software</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2007/a-tale-of-bad-exception-handling-in-finally-blocks-in-java/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Error Handling and Reliability</title>
		<link>http://www.basilv.com/psd/blog/2007/error-handling-and-reliability</link>
		<comments>http://www.basilv.com/psd/blog/2007/error-handling-and-reliability#comments</comments>
		<pubDate>Fri, 12 Jan 2007 15:00:44 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[reliability]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2007/error-handling-and-reliability</guid>
		<description><![CDATA[I have been thinking a lot lately about how to create reliable systems. I previously examined the link between complexity and reliability. Recently, however, I have come to appreciate the impact of error handling on reliability. For the purposes of this discussion, I consider two aspects of reliability: correctness - does the application produce the [...]]]></description>
			<content:encoded><![CDATA[<p>I have been thinking a lot lately about how to create reliable systems. I previously examined the link between <a href="http://www.basilv.com/psd/blog/2006/complexity-and-reliability">complexity and reliability</a>. Recently, however, I have come to appreciate the impact of error handling on reliability. For the purposes of this discussion, I consider two aspects of reliability: <em>correctness</em> - does the application produce the correct results, and <em>uptime</em> - the length of time the software can operate without terminating due to an error. A single defect or environmental problem can impact one or both of these measures. For example, a defect in an algorithm can cause a program to calculate the wrong result, without impacting uptime. A memory leak or network outage can impact uptime without impacting correctness. A null pointer exception impacts both. The error handling strategy you choose for your system affects both the correctness and the uptime. I am familiar with three main approaches to handling errors:</p>
<ul>
<li>Ignore errors</li>
<li>Fail fast</li>
<li>Degrade gracefully</li>
</ul>
<p>The <em>ignore errors</em> approach is very simple: assume errors will not happen and ignore them. Some of you may object that this is not a 'real' error handling strategy, but considering how often I have seen it used in production systems, I cannot agree. This approach does have the benefit of maximizing uptime: even if things go wrong, the program will keep running. Of course, if the program is producing incorrect output due to these errors, then you have a problem. So this approach tends to minimize correctness. Any problems that do occur are what I call <em>silent failures</em> that go undetected, at least for a while. Unix scripts and the C programming language adopt this strategy as the default: utilities and functions have return codes to report errors, so a call that results in an error will not affect the operation of your program or script unless you have an explicit check.</p>
<p>The <em>fail fast</em> approach is also very simple: whenever an error or unexpected event happens, immediately terminate execution. This approach tends to maximize correctness, but tends to minimizes uptime, since any abnormality causes it to end. These applications tend to be brittle. The slightest problem in the environment, such as a blip in the network, can bring down the application. Modern enterprise programming languages such as Java and C# adopt this strategy through the use of exceptions. If a problem occurs, an exception is thrown which will terminate the program unless explicitly caught and dealt with.</p>
<p>The <em>degrade gracefully</em> approach combines the best of the other two approaches. It detects errors like the fail fast approach, but instead of failing immediately, it handles the error and continues execution as appropriate. It therefore maximizes the reliability of the system by maximizing both correctness and uptime. The downside of this approach is that it requires much more thought and effort to implement. No programming language I am aware of provides explicit support for this approach.</p>
<p>I was originally a strong proponent of the fail fast approach, but last year I started to appreciate the degrade gracefully approach, as I wrote in my article <a href="http://www.basilv.com/psd/blog/2006/fail-fast-or-degrade-gracefully">Fail Fast or Degrade Gracefully?</a>. Over the past year, my viewpoint has shifted further. I now feel that the degrade gracefully approach should be used by default. Only if it would require too much effort or complexity to implement should the fail fast approach be used instead. (Naturally I do not support the use of the ignore errors approach.)</p>
<p>There are many examples of the degrade gracefully approach within the IT infrastructure we rely on. TCP/IP networking stacks are designed to degrade gracefully when problems such as dropped packets occur. Web servers do not shut down if a web application experiences a failure - they instead terminate the current request by sending an error response to the client and continue to serve other requests. Email clients do not fail if the email server becomes unavailable, and more importantly the mail you were trying to send is not lost. Modern compilers do not stop upon encountering the first syntax error but instead continue parsing the same file (and other files) as best they can.</p>
<p>The validity of these examples could be debated. One could argue that some of these situations such as dropped network packets and bad user input (syntax errors in code) are expected - a normal part of operation - rather than representing an exceptional situation or error. The systems handle these situations because it is a requirement, not because they are using the degrade gracefully error handling approach. I would instead argue that the requirement is to use the degrade gracefully approach to handle these problematic situations, primarily because both the ignore errors approach and the fail fast approach are unacceptable.</p>
<p>Reliable systems do not happen by accident, but require careful thought and effort to create. The approach you choose for handling errors can have a bigger impact on reliability than you might expect.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2007/error-handling-and-reliability/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lessons Learned in 2006</title>
		<link>http://www.basilv.com/psd/blog/2006/lessons-learned-in-2006</link>
		<comments>http://www.basilv.com/psd/blog/2006/lessons-learned-in-2006#comments</comments>
		<pubDate>Mon, 18 Dec 2006 20:43:35 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[learning]]></category>
		<category><![CDATA[professional]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[personal development]]></category>
		<category><![CDATA[reliability]]></category>
		<category><![CDATA[software releases]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2006/lessons-learned-in-2006</guid>
		<description><![CDATA[As a proponent of perpetual learning, I like to periodically take the time to reflect on what I have learned. Looking back at this past year, I definitely expanded my understanding in a number of areas based on my experiences at work and at home. My most significant growth was in the area of personal [...]]]></description>
			<content:encoded><![CDATA[<p>As a proponent of <a href="http://www.basilv.com/psd/blog/2006/perpetual-learning">perpetual learning</a>, I like to periodically take the time to reflect on what I have learned. Looking back at this past year, I definitely expanded my understanding in a number of areas based on my experiences at work and at home.</p>
<p>My most significant growth was in the area of personal productivity: I read and implemented the organizational system described in the book <a href="http://www.amazon.ca/exec/obidos/redirect?link_code=as2&#038;path=ASIN/0743520343&#038;tag=basilvandegri-20&#038;camp=15121&#038;creative=330641">Getting Things Done : The Art Of Stress-Free Productivity</a><img src="http://www.assoc-amazon.ca/e/ir?t=basilvandegri-20&#038;l=as2&#038;o=15&#038;a=0743520343" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> by David Allen. I have found this system very useful both at work and at home, and wrote an <a href="http://www.basilv.com/psd/blog/2006/getting-things-done">article describing my experience implementing the system</a>.</p>
<p>This last year I switched to a <a href="http://www.basilv.com/psd/blog/2006/working-four-days-a-week">four day work week</a>, and have found it to be a significant improvement over the normal five days. I even figured out how to do this without a drop in pay.</p>
<p>One area of software development I have explored a lot this year has been change and release management: specifically the process of promoting application or infrastructure changes into a production environment. Both my experiences at work and <a href="http://www.basilv.com/psd/blog/2006/running-my-website-3-month-retrospective">my experiences running this website</a> have made me appreciate the necessity of having a defined process. The amount of process that is necessary depends on the types of changes being made and the complexity of the environment. As I wrote in my article on <a href="http://www.basilv.com/psd/blog/2006/deploying-application-changes">deploying application changes</a>, it is easier when the application is packaged and deployed as a single unit. When this is not possible - like for database changes - then more process is necessary. Adding too much process, however, can be just as harmful as having too little - a proper balance must be maintained.</p>
<p>Over this last year I have spent a lot of time thinking about application reliability. Ensuring a system is highly reliable is a surprisingly difficult task, and one of the major culprits is <a href="http://www.basilv.com/psd/blog/2006/complexity-and-reliability">complexity</a>. I have found myself arguing more strongly for simpler, more reliable solutions as a result. My most recent focus has been on error handling.  My article on <a href="http://www.basilv.com/psd/blog/2006/fail-fast-or-degrade-gracefully">the fail fast and degrade gracefully approaches to error handling</a> contains some earlier thoughts on this subject, but I have not yet written up my latest ideas. I have come to believe that the degrade gracefully approach, while more difficult to implement, is the best for creating highly reliable software. I have unfortunately encountered a third approach to error handling: ignore errors. This leads to silent, undetected failures whose negative effects go unnoticed for an arbitrary length of time.</p>
<p>I have also learned a <a href="http://www.basilv.com/psd/blog/2006/running-my-website-3-month-retrospective">number of lessons from running this website</a>, including improving my knowledge of web design, promotion, and on-line advertising. I have found the process of writing my weekly articles to be a great learning aid. Writing forces me to reflect on and clarify my thoughts and ideas on a particular subject. It is no coincidence that I have provided a number of links above to articles I have written this past year. I tend to write about topics that are currently in my focus of attention, and the act of writing about them helps clarify and solidify the learning I have done. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2006/lessons-learned-in-2006/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Fail Fast or Degrade Gracefully?</title>
		<link>http://www.basilv.com/psd/blog/2006/fail-fast-or-degrade-gracefully</link>
		<comments>http://www.basilv.com/psd/blog/2006/fail-fast-or-degrade-gracefully#comments</comments>
		<pubDate>Thu, 09 Mar 2006 15:00:16 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[error handling]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2006/fail-fast-or-degrade-gracefully</guid>
		<description><![CDATA[There are two approaches to handling internal application errors. In the fail fast approach you immediately terminate the operation (or even the application) once an error is detected. In the degrade gracefully approach you try to continue with as much of the operation as you can. For quite a while I have been a firm [...]]]></description>
			<content:encoded><![CDATA[<p>There are two approaches to handling internal application errors. In the fail fast approach you immediately terminate the operation (or even the application) once an error is detected. In the degrade gracefully approach you try to continue with as much of the operation as you can.</p>
<p>For quite a while I have been a firm proponent of the fail fast approach. If you encounter an internal application error (i.e. a method parameter is unexpectedly null), this is often a sign of a defect. The presence of a defect means you can no longer trust the operation of the application, so the safest approach is to terminate the operation or even the application. (In Java, this is typically done by throwing an appropriate RuntimeException.) Besides being the safer of the two approaches, another advantage of fail fast is that it forces the problem into the open, which makes it more likely it will be detected and fixed.</p>
<p>However, I recently came across a situation in which the degrade gracefully approach made more sense. The application in question had a generic message class for formatting messages with parametrized arguments. To use the class, you provide the message embedded with tokens representing one or more parameters, plus the parameters to be substituted for the tokens. One day I came across a use of this message class that supplied a parametrized message with the wrong number of parameters. Curious as to why this block of code had not 'died' (thrown an exception) during testing, I looked into the implementation of this message class. I discovered that the class did absolutely no checking of the arguments supplied to it. As a result, you could supply the wrong number of parameters (too many or too few), and the class would still return the formatted string, ignoring extra parameters and treating missing parameters as empty strings. A little investigation quickly revealed that there were other places in the application that were supplying the wrong number of parameters to this class.</p>
<p>So I refactored the message class to use the fail fast approach, then searched for usages of the class to fix the cases where the arguments were invalid. It didn't take that long before the changes were done and all the unit tests were successful, so I committed my code. Some time later someone encountered an error which I quickly recognized - an invalid argument supplied to that generic message class. Obviously, I had missed a place in the application that was calling the message class incorrectly. But the error had me think: the message class was used to format a message to be displayed to the user. Before, with the degrade gracefully approach, the users had been able to perform the operation in question successfully, despite getting a poorly constructed message. Now with the fail fast approach, we did quickly find out about the bad message, but the user could no longer complete the work they were trying to do. I wasn't happy about my change having made the application less useful for the user.</p>
<p>After some thought, I realized that the degrade gracefully approach was appropriate in this situation. A message to the user missing some parameters is almost always still somewhat understandable, and has nothing to do with the actual business logic being performed, so it is fairly safe to continue with constructing the message despite receiving the incorrect number of parameters. But I still wanted to be able to find out about these cases - they did represent defects (albeit minor) in the code. I really wanted the advantages from both approaches.</p>
<p>To achieve this, I again refactored the message class to allow it to proceed despite having the wrong number of parameters. I changed the code checking for invalid parameters to log an error to the application log instead of throwing an exception. By logging an error I ensured that the developers would find out about the problem, but the application would proceed. (You may be thinking that this error in the log file is likely to be overlooked by developers, but I had already implemented changes to ensure this wouldn't happen. I'll save the details of this for a future article.)</p>
<p>In most cases, I still prefer the fail fast approach. Even in this case involving the message class, if the original developers had used the fail fast approach then I suspect there would have been far fewer cases of calling code supplying the wrong number of parameters. This is a potential drawback of the degrade gracefully approach: if you are not careful, you end up hiding information about a defect. If you do decide to use the degrade gracefully approach, ensure you have a mechanism to detect and reveal any defects, rather than completely hiding them. One case where the degrade gracefully approach is often used is at the application architecture level. Applications such as web servers and business web applications that process multiple independent operations do not terminate upon encountering an internal error. Instead, the current operation is terminated with the appropriate error reported while the application continues running, able to process other requests.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2006/fail-fast-or-degrade-gracefully/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

