1

I am using Go Chi with a custom handler function that returns an error.

Ideally I want to write a middleware function that uses my custom handler function and return an error that will eventually need to be handled. I will either handle the error in ServeHTTP or have a middleware function that handles all errors (so I can inject any logger I want).

I will handle the returned error in ServeHTTP. However, I need to have the ability to use a custom/ any logger.

Below is a rough outline of my approach.

// HandlerFunc that returns an error
type HandlerFunc func(w http.ResponseWriter, r *http.Request) error

type customHandler HandlerFunc

func (h customHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    err := h(w, r)
    if err != nil {
        // TODO: handle errors returned from handler here
    }
}

func main() {
    r := chi.NewRouter()

    r.Method(http.MethodGet, "/", customHandler(func(w http.ResponseWriter, req *http.Request) error {
        r.Use(useSomeMiddleware)

        // Handler logic ...

        // Hander returns an error. This will need to be handled
        return errors.New("error from handler")
    }))

    server := &http.Server{
        Addr:    fmt.Sprintf("%v:%v", "", "1337"),
        Handler: r,
    }

    err := server.ListenAndServe()
    if err != nil {
        log.Fatalf("main: starting server: %v", err)
    }
}

func useSomeMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Handler logic that could potentially return an error

        err := errors.New("handler error")
        if err != nil {
            // TODO: return error either to serveHTTP to handler or to a new error handler
            // middleware function
        }
    })
}

Update 1.

Ideally I want to write a middleware function that uses my custom handler function and return an error that will eventually need to be handled.

I can return errors from a middleware function that uses my custom handler function quite easily. So I can potentially handler errors in ServeHTTP. However I am still looking into an approach where I can build a new middleware and pass in a logger. Below is what my middleware function looks like.

func useSomeMiddleware(next http.Handler) http.Handler {
    return customHandler(func(w http.ResponseWriter, r *http.Request) error {
        err := errors.New("use some middleware error")
        if err != nil {
            return err
        }

        return nil
    })
}
Corbuk
  • 670
  • 1
  • 8
  • 23

0 Answers0