title: How to check deadlines in server middleware
body: <p>Per <a href="https://grpc.io/blog/deadlines/#checking-deadlines" rel="nofollow noreferrer">doc</a>, gRPC server could check deadlines as</p>
  <pre class="lang-golang prettyprint-override"><code>if ctx.Err() == context.Canceled {
      return status.New(codes.Canceled, &quot;Client cancelled, abandoning.&quot;)
  }
  </code></pre>
  <p>And I try to handle it in hello example</p>
  <pre class="lang-golang prettyprint-override"><code>// SayHello implements helloworld.GreeterServer
  func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
      log.Printf(&quot;Received: %v&quot;, in.GetName())
  
      select {
      case &lt;- time.After(time.Second):
          // simulate some operation here
      case &lt;- ctx.Done():
          if ctx.Err() == context.Canceled || ctx.Err() == context.DeadlineExceeded{
              return nil, status.New(codes.Canceled, &quot;Client cancelled, abandoning.&quot;).Err()
          }
      }
  
      return &amp;pb.HelloReply{Message: &quot;Hello &quot; + in.GetName()}, nil
  }
  </code></pre>
  <p>With test client codes</p>
  <pre class="lang-golang prettyprint-override"><code>    ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*600)
      defer cancel()
      r, err := c.SayHello(ctx, &amp;pb.HelloRequest{Name: name})
  </code></pre>
  <p>My question: how to check the deadline in middleware (or interceptor) in the gRPC server?</p>
  <p>What I have tried</p>
  <pre class="lang-golang prettyprint-override"><code>type serverStats struct {}
  
  func (h *serverStats) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
      fmt.Println(&quot;tag rpc&quot;)
      return ctx
  }
  
  func (h *serverStats) HandleRPC(ctx context.Context, s stats.RPCStats) {
      fmt.Println(&quot;handle rpc&quot;)
      if ctx.Err() == context.Canceled || ctx.Err() == context.DeadlineExceeded {
          fmt.Printf(&quot;HandleRPC: Client err %+v \n&quot;, ctx.Err())
      }
  }
  
  ...
  
      s := grpc.NewServer(grpc.StatsHandler(&amp;serverStats{}))
  </code></pre>
  <p>However, the <code>HandleRPC</code> is triggered multiple times, and it can NOT return error status codes.</p>