title: Deny Authentication in Servant.Auth with RIO
body: <p>I'm trying to combine Servant authentication (servant-auth-server package) with RIO as my handler monad to avoid the ExceptT anti-pattern. However, I can't line up the types properly for handling denied authentications.</p>
  <p>My (simplified) API endpoint is</p>
  <pre class="lang-hs prettyprint-override"><code>type UserEndpoint = &quot;user&quot; :&gt; (
                Get '[JSON] User                                       
          :&lt;|&gt;  ReqBody '[JSON] UpdatedUser :&gt; Put '[JSON] User        
      )
  </code></pre>
  <p>and the corresponding server</p>
  <pre class="lang-hs prettyprint-override"><code>protectedServer
    :: HasLogFunc m
    =&gt; AuthResult AuthUserId
    -&gt; ServerT UserEndpoint (RIO m)
  protectedServer (Authenticated authUser) =
    getUser authUser :&lt;|&gt; updateUser authUser
  -- Otherwise, we return a 401.
  protectedServer _ = throwIO err401
  </code></pre>
  <p>A type error arises in the branch for denied authentication:</p>
  <pre><code>    Could not deduce (MonadIO ((:&lt;|&gt;) (RIO m User)))
        arising from a use of ‘throwIO’
      [..]
  </code></pre>
  <p>I don't grok this type error. To my understanding (and given the signature of <code>protectedServer</code>), the return type should be <code>ServerT UserEndpoint (RIO m)</code>, which should have an instance of <code>MonadIO</code>, so that exception handling according to the <a href="https://www.fpcomplete.com/haskell/tutorial/exceptions/" rel="nofollow noreferrer">exceptions tutorial</a> should use <code>throwIO</code> instead of <code>throwAll</code> from <code>Servant.Auth.Server</code>. It seems that I haven't fully understood Servant's type machinery yet, where is my mistake?</p>
  <p>The two handler functions are defined as</p>
  <pre class="lang-hs prettyprint-override"><code>updateUser :: HasLogFunc m =&gt; AuthUserId -&gt; UpdatedUser -&gt; RIO m User
  updateUser authUser updateUser = ...
  
  getUser :: HasLogFunc m =&gt; AuthUserId -&gt; RIO m User
  getUser authUser = ...
  </code></pre>