<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonas Gauffin</title>
    <description>The latest articles on DEV Community by Jonas Gauffin (@jgauffin).</description>
    <link>https://dev.to/jgauffin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1108%2F818579.png</url>
      <title>DEV Community: Jonas Gauffin</title>
      <link>https://dev.to/jgauffin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jgauffin"/>
    <language>en</language>
    <item>
      <title>Exception handling explained</title>
      <dc:creator>Jonas Gauffin</dc:creator>
      <pubDate>Thu, 10 May 2018 11:33:24 +0000</pubDate>
      <link>https://dev.to/jgauffin/exception-handling-explained-ima</link>
      <guid>https://dev.to/jgauffin/exception-handling-explained-ima</guid>
      <description>&lt;p&gt;This article explains what exception handling is and how it differs from&lt;br&gt;
traditional error handling with error codes. The article does not get&lt;br&gt;
into usage or exception classes, but only to explain their purpose.&lt;/p&gt;

&lt;p&gt;Let's start with errors.&lt;/p&gt;
&lt;h1&gt;
  
  
  A brief introduction to error
&lt;/h1&gt;

&lt;p&gt;From the dawn of programming, error codes have been used to deal with errors in applications. An error code is used to indicate if the&lt;br&gt;
executed function was successful or not.&lt;/p&gt;

&lt;p&gt;Here is a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;SaveDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;accountName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetUserIdFromName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetAccountFromName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;StoreDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example illustrates that when you use error codes, it is the API&lt;br&gt;
consumer that must abort if something fails. You might, but how about&lt;br&gt;
the rest of the team, or those who maintained the application before&lt;br&gt;
you? It is like you would retire the entire police force and expect&lt;br&gt;
&lt;strong&gt;&lt;em&gt;all&lt;/em&gt;&lt;/strong&gt; citizens to behave and be good law abiding citizens.&lt;/p&gt;

&lt;p&gt;One developer could have been lazy and just written (or refactored) the&lt;br&gt;
code as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;SaveDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;accountName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetUserIdFromName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Arne"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetAccountFromName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Savings account"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;StoreDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that the code looks perfectly legal, but silently ignores&lt;br&gt;
errors. If you for instance mistakenly add a white space after all&lt;br&gt;
account names on the account selection page, the code above starts to&lt;br&gt;
fail silently. What's worse is that you will not know about it until&lt;br&gt;
code dependent upon the default account starts to fail, and that can be&lt;br&gt;
after a while. Tracking down that subsequent error can be challenging,&lt;br&gt;
primarily if the default account is set in different ways.&lt;/p&gt;

&lt;p&gt;Error codes are easy to get started with and can be quite powerful. Even&lt;br&gt;
modern languages like Go-lang uses errors instead of exceptions. Here is&lt;br&gt;
a go snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"filename.ext"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While errors are easy to understand and use, they have three&lt;br&gt;
significant drawbacks:&lt;/p&gt;
&lt;h2&gt;
  
  
  They do not convey context
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This section is for languages that only uses error codes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For instance, error code 2 means "File Not Found" in Windows. There is&lt;br&gt;
no way to state which file nor other information that might help you to&lt;br&gt;
understand why the file was missing. Error codes are just that. Codes&lt;br&gt;
that indicate a specific error, without context or clues.&lt;/p&gt;

&lt;p&gt;The problem with that is that it is hard to understand why or under what&lt;br&gt;
circumstances that the error occurred. The Windows API solves this by&lt;br&gt;
introducing a method called &lt;code&gt;GetLastError()&lt;/code&gt; which is used to get more&lt;br&gt;
information about the error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;OFSTRUCT&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;HFILE&lt;/span&gt; &lt;span class="n"&gt;hFile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;OpenFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"d:\\sample.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OF_READ&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hFile&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;HFILE_ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// all this is required to get the error message.&lt;/span&gt;
    &lt;span class="c1"&gt;// you typically add it to a separate function&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the error code, as hFile only indicates an error&lt;/span&gt;
    &lt;span class="c1"&gt;// but not which one.&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;errorCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetLastError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the generic error message which&lt;/span&gt;
    &lt;span class="c1"&gt;// represents the above error code.&lt;/span&gt;
    &lt;span class="n"&gt;LPVOID&lt;/span&gt; &lt;span class="n"&gt;lpMsgBuf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;LPVOID&lt;/span&gt; &lt;span class="n"&gt;lpDisplayBuf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;FormatMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;FORMAT_MESSAGE_ALLOCATE_BUFFER&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; 
        &lt;span class="n"&gt;FORMAT_MESSAGE_FROM_SYSTEM&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;FORMAT_MESSAGE_IGNORE_INSERTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;errorCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;MAKELANGID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LANG_NEUTRAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SUBLANG_DEFAULT&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LPTSTR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lpMsgBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My point is that an error code is not enough when you want to&lt;br&gt;
&lt;em&gt;solve&lt;/em&gt; the error.&lt;/p&gt;
&lt;h2&gt;
  
  
  The burden is on the function caller
&lt;/h2&gt;

&lt;p&gt;It is safe to say that all applications have errors, it is exceptionally&lt;br&gt;
rare (pun intended) that errors can be ignored. Ignoring errors might&lt;br&gt;
seem to work, but sooner or later consequential problems will surface.&lt;br&gt;
It will be much harder to find the root cause since the found error is&lt;br&gt;
just a consequence of the first one. Any kind of "fix" is just a&lt;br&gt;
workaround which clutters the code base but does not prevent the root&lt;br&gt;
cause from happening again.&lt;/p&gt;

&lt;p&gt;It is crucial that all errors are handled in your code. When you use&lt;br&gt;
error codes, it is so easy to ignore or forget errors. Had a tight&lt;br&gt;
deadline? Wrestled with an obscure bug or incomprehensible requirements?&lt;br&gt;
Those situations make it so easy to take a shortcut. If not all&lt;br&gt;
developers on your team have the same discipline, errors will get&lt;br&gt;
ignored.&lt;/p&gt;
&lt;h1&gt;
  
  
  Enter exceptions
&lt;/h1&gt;

&lt;p&gt;Exceptions are for exceptional situations. If something didn't go as&lt;br&gt;
expected, you got an exceptional situation.&lt;/p&gt;

&lt;p&gt;Sounds easy, huh?&lt;/p&gt;

&lt;p&gt;But what does that mean?&lt;/p&gt;
&lt;h2&gt;
  
  
  An exceptional example
&lt;/h2&gt;

&lt;p&gt;If you expect that something can fail, you should guard against that&lt;br&gt;
situation.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;/p&gt;

&lt;p&gt;Let's say that you love shopping the newest and hottest technical&lt;br&gt;
gadgets. When the new gadget is released, you want to be first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo83dfiz9eacxmggbl7pf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo83dfiz9eacxmggbl7pf.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario 1
&lt;/h3&gt;

&lt;p&gt;If you are like most of us, you can probably not just go on a shopping&lt;br&gt;
spree. You need to make sure that you have enough money.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Check your bank account.&lt;/li&gt;
&lt;li&gt; Go shopping.&lt;/li&gt;
&lt;li&gt; Pay&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Scenario 2
&lt;/h3&gt;

&lt;p&gt;However, if you are fortunate enough to have plenty of money, you can&lt;br&gt;
go shopping directly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go shopping.&lt;/li&gt;
&lt;li&gt; Pay&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  The difference
&lt;/h3&gt;

&lt;p&gt;In the first scenario, we have a known issue that we need to deal with:&lt;br&gt;
A money limit. Therefore, we always need to check that we have enough&lt;br&gt;
money. In the second scenario, we should have enough money.&lt;/p&gt;

&lt;p&gt;What happens if someone has hacked us in scenario 2:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Someone hacked us&lt;/li&gt;
&lt;li&gt; Go shopping&lt;/li&gt;
&lt;li&gt; Pay &amp;lt;-- Failed, no money&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In that case, we got an exception, since it is a case that shouldn't&lt;br&gt;
happen since we &lt;strong&gt;&lt;em&gt;expect&lt;/em&gt;&lt;/strong&gt; to have enough money.&lt;/p&gt;

&lt;p&gt;That is an exceptional situation.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;Why can't we always write the code like in scenario 1?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;First, it's about communicating intent. We mostly get a set of business&lt;br&gt;
requirements that we should fulfill. They tell us what to expect when&lt;br&gt;
implementing different use cases. If we go and add many checks for&lt;br&gt;
things that might, but should not, happen we lose the connection between&lt;br&gt;
our use cases and the code. It will be hard to tell the intent of the&lt;br&gt;
code, which in turn lead to assumptions and in the end decreased code&lt;br&gt;
quality.&lt;/p&gt;

&lt;p&gt;Second, if we add many checks we are coding workarounds as the real&lt;br&gt;
problem is that our account was hacked, not that we could not pay. By&lt;br&gt;
adding checks and abort instead of paying we are hiding that fact.&lt;/p&gt;
&lt;h2&gt;
  
  
  What exceptions are
&lt;/h2&gt;

&lt;p&gt;Exceptions are for situations that wasn't considered when defining what&lt;br&gt;
the application should do. When writing a messaging library for message&lt;br&gt;
queues you expect to receive complete messages, but when you write one&lt;br&gt;
for TCP you expect to receive partial messages. What's exceptional in&lt;br&gt;
one case doesn't necessarily have to be exceptional in another.&lt;/p&gt;

&lt;p&gt;If you would open a file there are several errors that can happen.&lt;br&gt;
Non-existent directory, file is missing, access denied, partial file,&lt;br&gt;
etc. All those errors are known to most programmers, so they are not&lt;br&gt;
exceptions, right?&lt;/p&gt;

&lt;p&gt;Wrong. In most cases, they are exceptions. Because you typically do&lt;br&gt;
expect that a file exists and that it's complete and readable. Well, if&lt;br&gt;
you are writing a data forensics application, most of those errors are&lt;br&gt;
expected and should be dealt with (and therefore not exceptional cases).&lt;/p&gt;
&lt;h3&gt;
  
  
  Exceptions exist to prevent your application from doing something stupid.
&lt;/h3&gt;

&lt;p&gt;It's crucial for you to understand that. Don't think of exceptions as&lt;br&gt;
something you can use to control your application when coding. Think of&lt;br&gt;
exceptions as a mechanism to guard against your application doing&lt;br&gt;
something wrong/unexpected.&lt;/p&gt;
&lt;h3&gt;
  
  
  Exceptions exist to help you fix problems in the future
&lt;/h3&gt;

&lt;p&gt;Since exceptions are not a flow control mechanism, they do add little&lt;br&gt;
value when executing your code (previously described point excluded).&lt;/p&gt;

&lt;p&gt;However, writing informative exception messages makes it much easier to&lt;br&gt;
correct future bugs, since they add context to the error. Always try to&lt;br&gt;
do so, your future self will thank you for it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code example
&lt;/h2&gt;

&lt;p&gt;Let's take the same code as was found in the beginning of this article,&lt;br&gt;
but changed to use exception handling instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SaveDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;accountName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetUserIdFromName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Arne"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetAccountFromName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Savings account"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;StoreDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the method now returns void as it does not need to&lt;br&gt;
indicate that everything went successfully. Nor does it need to validate&lt;br&gt;
error codes from the called methods. One can safely assume that an&lt;br&gt;
exception abort the processing if the expected result cannot be&lt;br&gt;
guaranteed.&lt;/p&gt;

&lt;p&gt;In fact, in most cases, we do not have to care if exceptions are thrown&lt;br&gt;
at all. Remember, exceptions are used to communicate that something&lt;br&gt;
unexpected happened. If we cannot predict it, how on earth could we be&lt;br&gt;
able to handle the exception?&lt;/p&gt;

&lt;p&gt;Let's look at the &lt;code&gt;StoreDefaultAccount&lt;/code&gt; method. The most important thing&lt;br&gt;
to understand is that the method says that a default account should be&lt;br&gt;
stored successfully. Since that is the method promise, we must throw an&lt;br&gt;
exception every time we find something that would prevent the default&lt;br&gt;
account from being stored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;StoreDefaultAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentOutOfRangeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"A valid user id must be specified."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentOutOfRangeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"A valid account id must be specified."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_accountRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerId&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"User &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; do not own account &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultAccount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;_userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first two exceptions are used to mitigate errors like parse errors&lt;br&gt;
or invalid data.&lt;/p&gt;

&lt;p&gt;The third exception is for a business rule. We may only use the user's&lt;br&gt;
own accounts as default accounts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_accountRepository.GetById(accountId);&lt;/code&gt; will in turn throw an&lt;br&gt;
exception if the given accountId do not exist in the database since the&lt;br&gt;
method name states that an account should be fetched.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;The purpose of exceptions is not to allow you to take different actions&lt;br&gt;
depending on if something failed or not. i.e. they are not a flow&lt;br&gt;
control mechanism. Instead, exceptions are used to make sure that your&lt;br&gt;
application delivers the expected result (or die trying).&lt;/p&gt;

&lt;p&gt;With that in mind, I hope that you find them as useful as I do. With&lt;br&gt;
the right mindset (and using exceptions) you can save much time since&lt;br&gt;
you do not have to track down why your database has a lot of data&lt;br&gt;
inconsistencies (which leads to bugs later).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is part of our exception handling series. To learn more, visit our &lt;a href="https://coderr.io/exception-handling/" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>exceptions</category>
      <category>errors</category>
    </item>
  </channel>
</rss>
