You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: recover.go
    path of file: ./repos/ente/server/pkg/middleware
    
    the code of the file until where you have to start completion: package middleware

import (
	"errors"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"
	"os"
	"runtime/debug"
	"strings"
	"syscall"

	"github.com/gin-contrib/requestid"
	"github.com/gin-gonic/gin"
	log "github.com/sirupsen/logrus"
)

// PanicRecover is similar to Gin's CustomRecoveryWithWriter but with custom logger.
// There's no easy way to plugin application logger instance & log custom attributes (like requestID)
func PanicRecover() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				// Check for a broken connection, as it is not really a
				// condition that warrants a panic stack trace.
				//
				// Newer versions of gin might fix this (the PR is not yet
				// merged as on writing):
				// https://github.com/gin-gonic/gin/pull/2150
				var brokenPipe bool

				// Legacy check, not sure if it ever worked. Retaining this, can
				// remove both when the gin PR is merged.
				if ne, ok := err.(*net.OpError); ok {
					if se, ok := ne.Err.(*os.SyscallError); ok {
						if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
							brokenPipe = true
						}
					}
				}

				// Newer check. Also untested.
				if !brokenPipe {
					if re, ok := err.(error); ok {
					
    
func PanicRecover() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				// Check for a broken connection, as it is not really a
				// condition that warrants a panic stack trace.
				//
				// Newer versions of gin might fix this (the PR is not yet
				// merged as on writing):
				// https://github.com/gin-gonic/gin/pull/2150
				var brokenPipe bool

				// Legacy check, not sure if it ever worked. Retaining this, can
				// remove both when the gin PR is merged.
				if ne, ok := err.(*net.OpError); ok {
					if se, ok := ne.Err.(*os.SyscallError); ok {
						if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
							brokenPipe = true
						}
					}
				}

				// Newer check. Also untested.
				if !brokenPipe {
					if re, ok := err.(error); ok {
						if errors.Is(re, syscall.EPIPE) {
							brokenPipe = true
						}
					}
				}

				httpRequest, _ := httputil.DumpRequest(c.Request, false)
				requestData := strings.Split(string(httpRequest), "\r\n")
				for idx, header := range requestData {
					current := strings.Split(header, ":")
					if current[0] == "Authorization" || current[0] == "X-Auth-Token" {
						requestData[idx] = current[0] + ": *"
					}
				}
				reqDataWithoutAuthHeaders := strings.Join(requestData, "\r\n")
				var logWithAttributes = log.WithFields(log.Fields{
					"request_data": reqDataWithoutAuthHeaders,
					"req_id":       requestid.Get(c),
					"req_uri":      c.Request.URL.Path,
					"panic":        err,
					"broken_pipe":  brokenPipe,
					"stack":        string(debug.Stack()),
				})
				if brokenPipe {
					log.Warn("Panic Recovery: Broken pipe")
					// If the connection is dead, we can't write a status to it.
					c.Error(err.(error)) // nolint: errcheck
					c.Abort()
					return
				}
				if fmt.Sprintf("%v", err) == "client disconnected" {
					// https://github.com/gin-gonic/gin/issues/2279#issuecomment-768349478
					logWithAttributes.Warn("Client request cancelled")
					c.Request.Context().Done()
				} else {
					logWithAttributes.Error("Recovery from Panic")
					c.AbortWithStatus(http.StatusInternalServerError)
				}
			}
		}()
		c.Next()
	}
}