{"id":4411,"date":"2015-07-29T13:00:04","date_gmt":"2015-07-29T13:00:04","guid":{"rendered":"http:\/\/writeasync.net\/?p=4411"},"modified":"2015-07-29T14:33:58","modified_gmt":"2015-07-29T14:33:58","slug":"worst-practices-exceptions","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=4411","title":{"rendered":"Worst practices: exceptions"},"content":{"rendered":"<p><a href=\"http:\/\/context-driven-testing.com\/\">There are no best practices.<\/a> But there are some pretty bad ones when it comes to exceptions. <a href=\"http:\/\/www.hans-eric.com\/2009\/10\/31\/the-bad-practices-of-exception-handling\/\">Hans-Eric Gr\u00f6nlund wrote about some of them<\/a> and I agree with his list. Here are a few more:<\/p>\n<h3>Breaking the contract<\/h3>\n<p>Languages like C# <a href=\"http:\/\/www.artima.com\/intv\/handcuffs.html\">do not have checked exceptions<\/a>. Nonetheless, <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms229030(v=vs.110).aspx\">exceptions are still part of the API contract<\/a>. If compatibility is important, e.g. when you are rolling out a <a href=\"http:\/\/semver.org\/\">minor version update<\/a>, you should not change the exception types thrown by existing methods.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ V1.1\r\npublic class NotCoolException : Exception { \/* ... *\/ }\r\n\r\npublic void EnsureCool()\r\n{\r\n    if (!cool)\r\n    {\r\n        throw new NotCoolException();\r\n    }\r\n}\r\n\r\n\/\/ V1.2\r\npublic class UncoolException : Exception { \/* ... *\/ }\r\n\r\npublic void EnsureCool()\r\n{\r\n    if (!cool)\r\n    {\r\n        \/\/ UH-OH... users upgrading from V1.1 won't be expecting this!\r\n        throw new UncoolException();\r\n    }\r\n}\r\n<\/pre>\n<p>Some client-friendly alternatives to augment error functionality without breaking anything:<\/p>\n<ul>\n<li>Create the new exception type from an existing base class already thrown by the method.<\/li>\n<li>Create a new class or method with enhanced error reporting functionality (and while you&#8217;re at it, mark the old method as <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.obsoleteattribute(v=vs.110).aspx\">[Obsolete]<\/a>).<\/li>\n<\/ul>\n<h3>Error monoculture<\/h3>\n<p>Have you ever seen code like this?<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic void DoSomethingComplicated()\r\n{\r\n    try\r\n    {\r\n        \/\/ complicated stuff ...\r\n    }\r\n    catch (TooTiredException e)\r\n    {\r\n        throw new BadThingHappenedException(&quot;Too tired to continue!&quot;, e);\r\n    }\r\n    catch (CableUnpluggedException e)\r\n    {\r\n        throw new BadThingHappenedException(&quot;Cable unplugged!&quot;, e);\r\n    }\r\n    catch (MachineOnFireException e)\r\n    {\r\n        throw new BadThingHappenedException(&quot;Machine on fire!&quot;, e);\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>If you&#8217;re using the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Facade_pattern\">fa\u00e7ade pattern<\/a> then all of this is completely acceptable. However, if you expect users to be able to employ distinct error handling techniques for distinct errors, then they&#8217;re out of luck. These poor users will be stuck with poor practices like dispatching on <a href=\"http:\/\/stackoverflow.com\/questions\/294622\/c-sharp-how-do-i-catch-an-exception-and-check-if-it-contains-a-string\">error message<\/a> or inner exception. If you&#8217;re faced with a defective API like this, considering making your own &#8220;exception beautifying&#8221; fa\u00e7ade along the lines <a href=\"http:\/\/writeasync.net\/?p=2911\">discussed in my earlier post<\/a>.<\/p>\n<h3>Logging overload<\/h3>\n<p>Do not feel compelled to log full exception details on every catch and every throw. While the terminology would suggest otherwise, a lot of exceptions are decidedly <em>not<\/em> exceptional. Imagine a client that supports transparent failover between primary and backup servers hosting a REST API. Logging the full stack trace on every transient timeout error received is probably going overboard (especially given the expected failover behavior &#8212; this is just <a href=\"http:\/\/netforbeginners.about.com\/od\/t\/f\/What-Is-TMI.htm\">TMI<\/a>). Consider instead logging only fatal errors or providing some feedback on abnormally pervasive error conditions. The first retry is not a big deal, but perhaps the 1000th is worrisome.<\/p>\n<p>Exceptions are always a <a href=\"http:\/\/blogs.msdn.com\/b\/dotnet\/archive\/2009\/02\/19\/why-catch-exception-empty-catch-is-bad.aspx\">source of controversy<\/a>. Please do your part and try not to make the exception landscape any more <a href=\"http:\/\/blogs.msdn.com\/b\/ericlippert\/archive\/2008\/09\/10\/vexing-exceptions.aspx\">vexing<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are no best practices. But there are some pretty bad ones when it comes to exceptions. Hans-Eric Gr\u00f6nlund wrote about some of them and I agree with his list. Here are a few more: Breaking the contract Languages like&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[91],"tags":[],"class_list":["post-4411","post","type-post","status-publish","format-standard","hentry","category-design"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/4411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4411"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/4411\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4411"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}