title: Throwing exceptions in switch statements when no specified case can be handled
body: <p>Let's say we have a function that changes a password for a user in a system in an MVC app.:</p>
  
  <pre><code>public JsonResult ChangePassword
      (string username, string currentPassword, string newPassword)
  {
      switch (this.membershipService.ValidateLogin(username, currentPassword))
      {
          case UserValidationResult.BasUsername:
          case UserValidationResult.BadPassword:
              // abort: return JsonResult with localized error message        
              // for invalid username/pass combo.
          case UserValidationResult.TrialExpired
              // abort: return JsonResult with localized error message
              // that user cannot login because their trial period has expired
          case UserValidationResult.Success:
              break;
      }
  
      // NOW change password now that user is validated
  }
  </code></pre>
  
  <p><code>membershipService.ValidateLogin()</code> returns a <code>UserValidationResult</code> enum that is defined as:</p>
  
  <pre><code>enum UserValidationResult
  {
      BadUsername,
      BadPassword,
      TrialExpired,
      Success
  }
  </code></pre>
  
  <p>Being a defensive programmer, I would change the above <code>ChangePassword()</code> method to throw an exception if there's an unrecognized <code>UserValidationResult</code> value back from <code>ValidateLogin()</code>:</p>
  
  <pre><code>public JsonResult ChangePassword
      (string username, string currentPassword, string newPassword)
  {
      switch (this.membershipService.ValidateLogin(username, currentPassword))
      {
          case UserValidationResult.BasUsername:
          case UserValidationResult.BadPassword:
              // abort: return JsonResult with localized error message        
              // for invalid username/pass combo.
          case UserValidationResult.TrialExpired
              // abort: return JsonResult with localized error message
              // that user cannot login because their trial period has expired
          case UserValidationResult.Success:
              break;
          default:
              throw new NotImplementedException
                  ("Unrecognized UserValidationResult value.");
              // or NotSupportedException()
              break;
      }
  
      // Change password now that user is validated
  }
  </code></pre>
  
  <p>I always considered a pattern like the last snippet above a best practice. For example, what if one developer gets a requirement that now when users try to login, if for this-or-that business reason, they're suppose to contact the business first? So <code>UserValidationResult</code>'s definition is updated to be:</p>
  
  <pre><code>enum UserValidationResult
  {
      BadUsername,
      BadPassword,
      TrialExpired,
      ContactUs,
      Success
  }
  </code></pre>
  
  <p>The developer changes the body of the <code>ValidateLogin()</code> method to return the new enum value (<code>UserValidationResult.ContactUs</code>) when applicable, but forgets to update <code>ChangePassword()</code>. Without the exception in the switch, the user is still allowed to change their password when their login attempt shouldn't even be validated in the first place!</p>
  
  <p>Is it just me, or is this <code>default: throw new Exception()</code> a good idea? I saw it some years ago and always (after groking it) assume it to be a best practice.</p>