title: Sentry MDC context and scope in futures
body: <p>I'm using Sentry to log errors in Scala Play application. I was trying to setup some additional information using MDC context and Sentry scope in ActionBuilder in order to add these information to each request.</p>
  <pre><code>class AuthenticatedUserAction @Inject()()) extends ActionBuilder[UserRequest, AnyContent]{
  
    override def invokeBlock[A](request: Request[A], block: UserRequest[A] =&gt; Future[Result]): Future[Result] = {
       //...Non-relevant code
      requestClaim.value.flatMap {
         case Right(jwtClaim) =&gt; getRequestUser(tenantOpt, request, lang).flatMap {
         case Right(requestUser) =&gt;
           
           enrichLogger(request, requestUser, tenantOpt)
           val b = block(UserRequest(jwtClaim, request, requestUser))
           clearLogger()
           b
  
      case Left(error) =&gt; 
    }
    case Left(_) =&gt; Future.successful(authRouting.onUnauthenticated())
   }
  }
  
  private def enrichLogger[A](request: Request[A], requestUser: RequestUser, tenantOpt: Option[Tenant]): Unit = {
    MDC.put(&quot;user&quot;, requestUser.email.value)
    MDC.put(&quot;tenant&quot;, tenantOpt.map(_.name).get)
    MDC.put(&quot;uri&quot;, request.uri)
    MDC.put(&quot;domain&quot;, request.domain)
    MDC.put(&quot;method&quot;, request.method)
    MDC.put(&quot;site&quot;, getSiteType(request.domain).toString)
    if (request.hasBody) MDC.put(&quot;request-body&quot;, request.body.toString)
    Sentry.configureScope(scope =&gt; {
      val user = new User()
      user.setEmail(requestUser.email.value)
      user.setOthers(
        Map(
          &quot;name&quot; -&gt; requestUser.name,
          &quot;userId&quot; -&gt; requestUser.userId.toString).asJava)
       scope.setUser(user)
  })
  }
  private def clearLogger(): Unit = {
    MDC.clear()
    import io.sentry.Sentry
    Sentry.configureScope((scope) =&gt; {
    scope.setUser(null)
  })
  }
  </code></pre>
  <p>This would work when I have single thread endpoint like this:</p>
  <pre><code>def error = authUserAction ( implicit request =&gt; {
    try{
      unsafeMethod
    } catch {
      case e: UnsupportedOperationException =&gt; logger.error(&quot;Sentry test exception caught&quot;, e)
    }
    Ok(&quot;Test Sentry in admin&quot;)
  })
  </code></pre>
  <p>However, most of the endpoints I have in application use futures, like in this simplified example:</p>
  <pre><code>def errorInFuture = authUserAction.async ( implicit request =&gt; {
    for {
      users &lt;- EitherT(usersRepo.list()) ?| respond500 _
    } yield Ok(Json.toJson(users)
  })
  </code></pre>
  <p>My question is if it's possible to solve the issue and set MDC context and/or sentry scope without having to change every single endpoint.</p>