<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>bert hubert finally blogs: The perfect error message</title>
  <subtitle type="html">code, musings and more</subtitle>
  <id>tag:blog.netherlabs.nl,2005:Typo</id>
  <generator version="4.0" uri="http://www.typosphere.org">Typo</generator>
  <link href="http://blog.netherlabs.nl/xml/atom/article/7900/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message" rel="alternate" type="text/html"/>
  <updated>2006-09-08T16:48:12+02:00</updated>
  <entry>
    <author>
      <name>bert hubert</name>
      <email>bert.hubert@netherlabs.nl</email>
    </author>
    <id>urn:uuid:34c6bf3d-0bc1-4c52-84c7-65b39cdf8b6e</id>
    <published>2006-09-08T15:36:00+02:00</published>
    <updated>2006-09-08T16:48:12+02:00</updated>
    <title type="html">The perfect error message</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message" rel="alternate" type="text/html"/>
    <category term="linux" scheme="http://blog.netherlabs.nl/articles/category/linux" label="Linux"/>
    <category term="powerdns" scheme="http://blog.netherlabs.nl/articles/category/powerdns" label="PowerDNS"/>
    <category term="netherlabs" scheme="http://blog.netherlabs.nl/articles/category/netherlabs" label="Netherlabs"/>
    <summary type="html">&lt;p&gt;Programming is a lot of things. One of them is writing good error messages. We tend to think that errors are rare and this should of course be so. However, sometimes they are not, and in that case, good reporting is vital to  quickly resolve the problem.&lt;/p&gt;

&lt;p&gt;So, even though we should make sure errors do not happen, if they do, our error messages should be top notch.&lt;/p&gt;

&lt;h1&gt;About error messages&lt;/h1&gt;

&lt;h2&gt;Purpose &lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For operators, they are vital aids in configuring software&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For system adminstrators, they show which external problems need to be resolved (disk full, network down, etc).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should a program crash, the authors often only have error messages as clues to why this happened. Many crashes are preceded by errors that are reported. A good error can help generate a bug fix.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Taxonomy of error messages&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Configuration problems, for example, looking for a file in directory A while it resides in directory B;&lt;/li&gt;
&lt;li&gt;Unavailable resources (disk full, out of memory), connectivity problems;&lt;/li&gt;
&lt;li&gt;Should Never Happen.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Configuration problems&lt;/h2&gt;

&lt;p&gt;These commonly occur while software is being installed and setup. Good error reporting is of utmost importance here, as it serves two purposes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Educating the operator about how the program functions;&lt;/li&gt;
&lt;li&gt;Explaining what needs to be fixed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ad 1, an error like &amp;#8220;Can&amp;#8217;t start frobnicator because the discombulator is not running&amp;#8221; teaches the operator that a frobnicator needs a discombulator. This knowledge can of course also be gleened from the documentation, but in this case, repetition is a good thing. &lt;/p&gt;

&lt;p&gt;Compare this error to &amp;#8220;Can&amp;#8217;t start process: Connection refused&amp;#8221;, for example, and think about how helpful that is.&lt;/p&gt;

&lt;p&gt;Ad 2, a report like &amp;#8220;Can&amp;#8217;t connect to product database using connection string &amp;#8216;dbuser=john, dbname=changeme&amp;#8217;: No such database&amp;#8221; immediately tells the operator what he needs to know.&lt;/p&gt;

&lt;h2&gt;Unavailable resources&lt;/h2&gt;

&lt;p&gt;These typically occur while a program is already running and installed, but are nonetheless important. Do not log &amp;#8216;Disk full&amp;#8217;, but report &amp;#8216;Disk full writing to &amp;#8230;.&amp;#8217; so the operator knows which disk filled up. If a server could not be reached, log the IP address and possibly the name of the server. Any discrepancy between the two may point out a DNS configuration error.&lt;/p&gt;

&lt;p&gt;Out of memory is typically very hard to deal with, except when something really odd was going on. A typical example is trying to allocate a ridiculous amount of memory because of an earlier error, in which case logging what memory was being allocated for might help debug the problem. It typically will not help the user of a program.&lt;/p&gt;

&lt;h2&gt;Should never happen&lt;/h2&gt;

&lt;p&gt;These are errors of the program itself. Programmers quite often test for impossible conditions, especially if they sense these might conceivably happen one day. An example might be a module that can only connect to IPv4 servers that gets confronted by an IPv6 socket, which in turn leads calls to determine the IPv4 remote address to fail. &lt;/p&gt;

&lt;p&gt;It is tempting to be quite rude in these messages, or say stuff like &amp;#8220;should never happen!!&amp;#8221;, but resist these urges. One day a &amp;#8216;should not happen&amp;#8217; error is going to be a vital debugging clue. These errors are rare, but it pays to go, well, the extra few yards to perhaps report &amp;#8220;unexpected address family accepting connection!&amp;#8221;.&lt;/p&gt;

&lt;h1&gt;Guidelines&lt;/h1&gt;

&lt;p&gt;An error message should contain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who is reporting the error (which subsystem, which program, which module)&lt;/li&gt;
&lt;li&gt;The action that failed&lt;/li&gt;
&lt;li&gt;The subject of the action (a directory, a server, a port number, an IP address)&lt;/li&gt;
&lt;li&gt;As good an indication of the actual error as possible.&lt;/li&gt;
&lt;li&gt;Optional - what the program is doing about it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An excellent error message is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Webserver can't serve page, error opening file '/var/www/index.html': Permission denied, reporting HTTP 404 error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ad 1, it is tempting to include filenames, function names, and line numbers here. OpenSSL does this a lot, for example. However, almost none of your intended audience will be able to extract useful information from the fact that the error occurred on line 123 of &amp;#8216;multiplexer.c&amp;#8217;. Make sure the module means something to the operator. It may be as simple as the name of your program.&lt;/p&gt;

&lt;p&gt;Ad 2, this helps the operator determine if this error might be the explanation of observed problems. An error like &amp;#8220;Webserver failed to increase TCP buffer size, continuing with default&amp;#8221; can immediately be ruled out as an explanation for why people can&amp;#8217;t log in to their mail.&lt;/p&gt;

&lt;p&gt;Ad 3, an error like &amp;#8220;Can&amp;#8217;t open file&amp;#8221; on its own can mean many things. One of which might be that it is not reading the configuration file you think it is, and trying to open your index.html in &amp;#8216;/usr/local/www&amp;#8217;, and not in &amp;#8216;/var/www&amp;#8217; like you thought you configured. &lt;/p&gt;

&lt;p&gt;Ad 4, self explanatory. Take the trouble to convert error codes into strings. Many programmers may know what &amp;#8216;errno = 111&amp;#8217; means &amp;#8216;Connection refused&amp;#8217;, but don&amp;#8217;t count on your users knowing this.&lt;/p&gt;

&lt;p&gt;Ad 5, this is a fine counterpoint to item 4. &amp;#8220;Giving a 404&amp;#8221; is very clear for any operator of a web server. Not all errors need a followup, so reporting what the program is doing about the error is not mandatory.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Good error messages can save your users many days of problems. And, suprisingly, you might yourself gain even more time - how well do you know the internals of your program after a few months? &lt;/p&gt;

&lt;p&gt;So please please, both as a user and a progammer, I ask you, spend time on error messages!&lt;/p&gt;</summary>
    <content type="html">&lt;p&gt;Programming is a lot of things. One of them is writing good error messages. We tend to think that errors are rare and this should of course be so. However, sometimes they are not, and in that case, good reporting is vital to  quickly resolve the problem.&lt;/p&gt;

&lt;p&gt;So, even though we should make sure errors do not happen, if they do, our error messages should be top notch.&lt;/p&gt;

&lt;h1&gt;About error messages&lt;/h1&gt;

&lt;h2&gt;Purpose &lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For operators, they are vital aids in configuring software&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For system adminstrators, they show which external problems need to be resolved (disk full, network down, etc).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should a program crash, the authors often only have error messages as clues to why this happened. Many crashes are preceded by errors that are reported. A good error can help generate a bug fix.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Taxonomy of error messages&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Configuration problems, for example, looking for a file in directory A while it resides in directory B;&lt;/li&gt;
&lt;li&gt;Unavailable resources (disk full, out of memory), connectivity problems;&lt;/li&gt;
&lt;li&gt;Should Never Happen.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Configuration problems&lt;/h2&gt;

&lt;p&gt;These commonly occur while software is being installed and setup. Good error reporting is of utmost importance here, as it serves two purposes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Educating the operator about how the program functions;&lt;/li&gt;
&lt;li&gt;Explaining what needs to be fixed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ad 1, an error like &amp;#8220;Can&amp;#8217;t start frobnicator because the discombulator is not running&amp;#8221; teaches the operator that a frobnicator needs a discombulator. This knowledge can of course also be gleened from the documentation, but in this case, repetition is a good thing. &lt;/p&gt;

&lt;p&gt;Compare this error to &amp;#8220;Can&amp;#8217;t start process: Connection refused&amp;#8221;, for example, and think about how helpful that is.&lt;/p&gt;

&lt;p&gt;Ad 2, a report like &amp;#8220;Can&amp;#8217;t connect to product database using connection string &amp;#8216;dbuser=john, dbname=changeme&amp;#8217;: No such database&amp;#8221; immediately tells the operator what he needs to know.&lt;/p&gt;

&lt;h2&gt;Unavailable resources&lt;/h2&gt;

&lt;p&gt;These typically occur while a program is already running and installed, but are nonetheless important. Do not log &amp;#8216;Disk full&amp;#8217;, but report &amp;#8216;Disk full writing to &amp;#8230;.&amp;#8217; so the operator knows which disk filled up. If a server could not be reached, log the IP address and possibly the name of the server. Any discrepancy between the two may point out a DNS configuration error.&lt;/p&gt;

&lt;p&gt;Out of memory is typically very hard to deal with, except when something really odd was going on. A typical example is trying to allocate a ridiculous amount of memory because of an earlier error, in which case logging what memory was being allocated for might help debug the problem. It typically will not help the user of a program.&lt;/p&gt;

&lt;h2&gt;Should never happen&lt;/h2&gt;

&lt;p&gt;These are errors of the program itself. Programmers quite often test for impossible conditions, especially if they sense these might conceivably happen one day. An example might be a module that can only connect to IPv4 servers that gets confronted by an IPv6 socket, which in turn leads calls to determine the IPv4 remote address to fail. &lt;/p&gt;

&lt;p&gt;It is tempting to be quite rude in these messages, or say stuff like &amp;#8220;should never happen!!&amp;#8221;, but resist these urges. One day a &amp;#8216;should not happen&amp;#8217; error is going to be a vital debugging clue. These errors are rare, but it pays to go, well, the extra few yards to perhaps report &amp;#8220;unexpected address family accepting connection!&amp;#8221;.&lt;/p&gt;

&lt;h1&gt;Guidelines&lt;/h1&gt;

&lt;p&gt;An error message should contain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who is reporting the error (which subsystem, which program, which module)&lt;/li&gt;
&lt;li&gt;The action that failed&lt;/li&gt;
&lt;li&gt;The subject of the action (a directory, a server, a port number, an IP address)&lt;/li&gt;
&lt;li&gt;As good an indication of the actual error as possible.&lt;/li&gt;
&lt;li&gt;Optional - what the program is doing about it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An excellent error message is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Webserver can't serve page, error opening file '/var/www/index.html': Permission denied, reporting HTTP 404 error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ad 1, it is tempting to include filenames, function names, and line numbers here. OpenSSL does this a lot, for example. However, almost none of your intended audience will be able to extract useful information from the fact that the error occurred on line 123 of &amp;#8216;multiplexer.c&amp;#8217;. Make sure the module means something to the operator. It may be as simple as the name of your program.&lt;/p&gt;

&lt;p&gt;Ad 2, this helps the operator determine if this error might be the explanation of observed problems. An error like &amp;#8220;Webserver failed to increase TCP buffer size, continuing with default&amp;#8221; can immediately be ruled out as an explanation for why people can&amp;#8217;t log in to their mail.&lt;/p&gt;

&lt;p&gt;Ad 3, an error like &amp;#8220;Can&amp;#8217;t open file&amp;#8221; on its own can mean many things. One of which might be that it is not reading the configuration file you think it is, and trying to open your index.html in &amp;#8216;/usr/local/www&amp;#8217;, and not in &amp;#8216;/var/www&amp;#8217; like you thought you configured. &lt;/p&gt;

&lt;p&gt;Ad 4, self explanatory. Take the trouble to convert error codes into strings. Many programmers may know what &amp;#8216;errno = 111&amp;#8217; means &amp;#8216;Connection refused&amp;#8217;, but don&amp;#8217;t count on your users knowing this.&lt;/p&gt;

&lt;p&gt;Ad 5, this is a fine counterpoint to item 4. &amp;#8220;Giving a 404&amp;#8221; is very clear for any operator of a web server. Not all errors need a followup, so reporting what the program is doing about the error is not mandatory.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Good error messages can save your users many days of problems. And, suprisingly, you might yourself gain even more time - how well do you know the internals of your program after a few months? &lt;/p&gt;

&lt;p&gt;So please please, both as a user and a progammer, I ask you, spend time on error messages!&lt;/p&gt;</content>
  </entry>
  <entry>
    <author>
      <name>8th street latinas</name>
    </author>
    <id>urn:uuid:dcbb8bca-cd94-427f-9ace-ec00acca6822</id>
    <published>2007-05-25T09:46:22+02:00</published>
    <updated>2007-05-25T09:46:22+02:00</updated>
    <title type="html">Comment on The perfect error message by 8th street latinas</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-127519" rel="alternate" type="text/html"/>
    <content type="html">Try validator.w3.org should help</content>
  </entry>
  <entry>
    <author>
      <name>ass parade</name>
    </author>
    <id>urn:uuid:61ae9de6-8932-4730-8c45-a7a174043230</id>
    <published>2007-05-24T23:35:38+02:00</published>
    <updated>2007-05-24T23:35:38+02:00</updated>
    <title type="html">Comment on The perfect error message by ass parade</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-126833" rel="alternate" type="text/html"/>
    <content type="html">Recommend me please some validator, so that i could optimize my html!</content>
  </entry>
  <entry>
    <author>
      <name>crissy moran</name>
    </author>
    <id>urn:uuid:9b2ecd5c-11a9-4204-b3bd-fbae833dae58</id>
    <published>2007-05-24T14:19:29+02:00</published>
    <updated>2007-05-24T14:19:29+02:00</updated>
    <title type="html">Comment on The perfect error message by crissy moran</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-126393" rel="alternate" type="text/html"/>
    <content type="html">i want to ask if it is possible to create different mysql base and keep there old not needed messages?</content>
  </entry>
  <entry>
    <author>
      <name>sky lopez</name>
    </author>
    <id>urn:uuid:94176563-166f-42f2-af71-00576b3a0b85</id>
    <published>2007-05-24T00:21:22+02:00</published>
    <updated>2007-05-24T00:21:22+02:00</updated>
    <title type="html">Comment on The perfect error message by sky lopez</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-125537" rel="alternate" type="text/html"/>
    <content type="html">Programming is so exciting, you should definetely try it!</content>
  </entry>
  <entry>
    <author>
      <name>tera patrick</name>
    </author>
    <id>urn:uuid:3877f94f-9853-4c7e-95a3-4dff8a6ae742</id>
    <published>2007-05-23T13:28:33+02:00</published>
    <updated>2007-05-23T13:28:33+02:00</updated>
    <title type="html">Comment on The perfect error message by tera patrick</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-124909" rel="alternate" type="text/html"/>
    <content type="html">Common mistake is not checking just created sites in all possible browsers, in order to see everything is correct!</content>
  </entry>
  <entry>
    <author>
      <name>round and brown</name>
    </author>
    <id>urn:uuid:c07521c5-a1bc-4e5a-a5bb-63590c5b51b0</id>
    <published>2007-05-23T01:44:24+02:00</published>
    <updated>2007-05-23T01:44:24+02:00</updated>
    <title type="html">Comment on The perfect error message by round and brown</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-124181" rel="alternate" type="text/html"/>
    <content type="html">Advice me please mass podcast site for free usage</content>
  </entry>
  <entry>
    <author>
      <name>milf hunter</name>
    </author>
    <id>urn:uuid:770f8b94-4123-4b3f-9ea5-ee1f1aa8147b</id>
    <published>2007-05-22T13:56:16+02:00</published>
    <updated>2007-05-22T13:56:16+02:00</updated>
    <title type="html">Comment on The perfect error message by milf hunter</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-123513" rel="alternate" type="text/html"/>
    <content type="html">I am curious how do you manage all posts? is there a html editor fur ruby or rails?</content>
  </entry>
  <entry>
    <author>
      <name>big naturals</name>
    </author>
    <id>urn:uuid:be528a89-2968-4ac1-9ead-1b9e5a8af852</id>
    <published>2007-05-21T14:04:56+02:00</published>
    <updated>2007-05-21T14:04:56+02:00</updated>
    <title type="html">Comment on The perfect error message by big naturals</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-122403" rel="alternate" type="text/html"/>
    <content type="html">How to set up RSS of blogs on ruby?</content>
  </entry>
  <entry>
    <author>
      <name>raven riley</name>
    </author>
    <id>urn:uuid:2e550f81-6795-4259-b9bb-b864f44d38b7</id>
    <published>2007-05-18T18:48:29+02:00</published>
    <updated>2007-05-18T18:48:29+02:00</updated>
    <title type="html">Comment on The perfect error message by raven riley</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-120991" rel="alternate" type="text/html"/>
    <content type="html">For normal matrix degenerate own values is the freedom to define the eigenvector corresponding quaternion own values related to the replacement of any linear combination!</content>
  </entry>
  <entry>
    <author>
      <name>Jenna Haze</name>
    </author>
    <id>urn:uuid:7191610e-f923-4426-a8f0-7cca0d99f281</id>
    <published>2007-05-16T18:13:38+02:00</published>
    <updated>2007-05-16T18:13:38+02:00</updated>
    <title type="html">Comment on The perfect error message by Jenna Haze</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-117749" rel="alternate" type="text/html"/>
    <content type="html">it's so hard nowadays to find some original admin tools for blogs that are free to use, can anyone advice any to form multi language posts?</content>
  </entry>
  <entry>
    <author>
      <name>we live together</name>
    </author>
    <id>urn:uuid:4c61dd07-06ed-439c-bdff-7b363c996da5</id>
    <published>2007-05-09T17:04:11+02:00</published>
    <updated>2007-05-09T17:04:11+02:00</updated>
    <title type="html">Comment on The perfect error message by we live together</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-108743" rel="alternate" type="text/html"/>
    <content type="html">Predicted values in template editing can be done through any PHP script?</content>
  </entry>
  <entry>
    <author>
      <name>ashish</name>
    </author>
    <id>urn:uuid:38a47437-a412-4eb1-a732-3d7751af2bb7</id>
    <published>2006-12-21T08:42:57+01:00</published>
    <updated>2006-12-21T08:42:57+01:00</updated>
    <title type="html">Comment on The perfect error message by ashish</title>
    <link href="http://blog.netherlabs.nl/articles/2006/09/08/the-perfect-error-message#comment-32597" rel="alternate" type="text/html"/>
    <content type="html">Below link provide a new way to generate and manage error messages.

&lt;a href="http://www.conman.org/projects/essays/magicnum.html"&gt;http://www.conman.org/projects/essays/magicnum.html&lt;/a&gt;</content>
  </entry>
</feed>

