Why Golang HTTP Handlers Should Return An Error

Поділитися
Вставка
  • Опубліковано 20 жов 2024

КОМЕНТАРІ • 53

  • @anthonygg_
    @anthonygg_  6 місяців тому +2

    ► 33% OFF on my Go + HTMX + Templ Course PRESALE 👉bit.ly/3UFruxO
    ► Join my Discord community for free education 👉 discord.com/invite/Ac7CWREe58
    ► Exclusive Lessons, Mentorship, And Videos 👉 www.patreon.com/anthonygg_
    ► 60% OFF on my Golang course 👉 fulltimegodev.com
    Thanks for watching

  • @eptic-c
    @eptic-c 6 місяців тому +40

    The biggest problem on the internet is that everybody talks like they are experts but they never encountered real problems because they never needed real solutions.

    • @rafael.aloizio1769
      @rafael.aloizio1769 6 місяців тому

      You did a hell of a surgery here, congrats

    • @hjnp
      @hjnp 6 місяців тому

      true la palisse!

  • @henrythomas6356
    @henrythomas6356 6 місяців тому +8

    100% agree, almost everywhere you look in Golang where errors may occur they are returned.
    The HTTP handlers deviating from this feels wrong and results in hacky middleware solutions.

  • @iliatalebzade8751
    @iliatalebzade8751 6 місяців тому +14

    It is the correct way when the handlers return an error, the example you showed was more than enough proof that it makes the code 100x better to have handlers return errors, but with standard libraries within each language there's a line of having all these utility and tools included in the best and most accessible shape while maintaining a certain level of keeping the tools "vanilla" so that each developer based on their specific needs can use them and utilize them, so with that I think not having handlers return an error is not a bad choice made by maintainers.
    Love your work, learned a ton from you, wish you the best 🔥🔥🔥

    • @anthonygg_
      @anthonygg_  6 місяців тому +4

      This makes sense. You have a point.

  • @mojixcoder
    @mojixcoder 6 місяців тому +13

    Returning an error by HTTP handlers makes it really hard for other middlewares to find the correct and final response status code. Because global error handler gets called after all middlewares and handlers. I don’t agree with that.

    • @turkishcat4423
      @turkishcat4423 6 місяців тому +3

      I think you didn’t understand the example in the video…

    • @mojixcoder
      @mojixcoder 6 місяців тому +1

      @@turkishcat4423I didn’t specifically talked about the video, I was talking about talking a concept in which you can handle errors after everything is finished in HTTP handlers.

    • @daderler4986
      @daderler4986 6 місяців тому +5

      @@mojixcoder The makeHandler() function writes the error in the response if the actual handler returns one. So middlewares will be able to read the response code and everything by looking at the response itself, like usual.

    • @jackielii
      @jackielii 6 місяців тому

      I agree, IMHO the std http.Handler stays closest to the data flow model. You get the request, and the writer to write to the TCP stream. It gives maximum flexibility to what you need to achieve without having to thinking too much.
      I agree returning an error may make writing the handlers easier (70%? 90%?) in terms of LOC.
      A couple of month ago I wrote an nextjs chat app. I initially used the new App router which takes a request and returns an response. I had to switch to the old Pages router which passes in the response writer and request. Although one can achieve the same thing with both, but it's much easier to reason with the response writer passed in.

    • @mojixcoder
      @mojixcoder 6 місяців тому

      @@daderler4986 in this example yes, but in other frameworks like echo it not designed like this and cant be designed like that. This is just a simple example and writing a wrapper around the stdlib. By doing so in a package like echo, all middlewares have to check returned errors as well as the response status code to predict the correct status code.

  • @dhanielr
    @dhanielr 6 місяців тому +10

    You are completely right. I work with Go about 4 years ago and before that i work with OOP languages. Don't get me wrong, i love to work with Go, but sometimes the community hugs to much the symplicity and when whe talk about scalability most of the times this is realy bad. This idea you put on the video is a simple application for adapter pattern and even that, the community repudiates. Very good video.

  • @P3PPING
    @P3PPING 6 місяців тому +4

    The stdlib is written in such a way to make error handling your problem and not theirs. By not returning errors and forcing the developer to implement and handle them as they see fit is the correct implementation.
    Otherwise it becomes too opinionated and there are too many default cases the stdlib has to provide behaviour for.
    Stdlib only exists to provide the building blocks, its not there to tell you how to hang your curtains.
    I do like how you handle your errors though.

  • @paulbinkim6409
    @paulbinkim6409 6 місяців тому +2

    The reason why returning error is at one point becomes necessary is because handling error at your handler forces you to be context aware. Like Anthony showed in this video, you will have multiple different error types, then sentinel errors, network errors, where each needs to be handled different way. Imagine you having 100 handlers that does exhaustive error handling for 5~10 different cases and tell me error handling is doable...

  • @vyrwu
    @vyrwu 6 місяців тому +8

    You can easily wrap handlers in funcs like you showed. Someone might have a different opinion and choose to handle each error separately. No need to add this behaviour to std lib if you can implement this in 5 mins by wrapping handlers. Don’t understand the discussion.

  • @rodjenihm
    @rodjenihm 6 місяців тому +10

    Definitely makes handler cleaner.

  • @rolandinmarsat4309
    @rolandinmarsat4309 6 місяців тому +1

    Your approach makes more sense. I hadn't yet thought of implementing it the way you've shown. Although it is so obvious. This is an easier way to centralize error handling on an http server. Thank you!

  • @arturfil
    @arturfil 6 місяців тому +2

    Hey that's my comment! lol.
    I don't mind changing the way I code my project if I see a better way of doing so. I just don't personally see the need to return an error in the handler. I do return an error in the service itself or log the error in the handler, but I don't return it simply because I just setup the routes to the server struct and declare the controllers in the router setup.
    Also, I know that just because everyone does it in x way doesn't mean is right BUT they way I've seen handlers created, in books and articles and courses, is by not returning an error, but in the services instead because that's where an error could potentially come. If there is a potential error in the handler by setup, then I would just log it.
    Also, if you say there would be problems when logging errors, I do have helper functions that have a structured Error and returns that as JSON so that way if I need to change something I can reference to the struct and unfortunately yes, change all the writeError function instances.
    But again, I'm always open and happy to change the way I structure my code if I see a better way of doing so.

  • @vitiok78
    @vitiok78 6 місяців тому +4

    Anthony, please, don't be so angry when people tell you the truth about the errors and the lack of point to return them.
    Did you know why the Request variable in handle functions comes as a pointer and has the context inside? This is exactly the reason! You can add any values to that context and use them later in any middleware. So you can add errors in context and wrap the handler in WithErrorHandlingMiddleware. Here you will read that context from Request and use it how you want))) And the signature of your handler functions remains standard

    • @anthonygg_
      @anthonygg_  6 місяців тому +3

      Everyone is free to write and handle code as they please. Im just sharing my experience utilising this way of error handling. This is how Docker api does and how my 40 million dollar evaluated company does it. We are still friends.

    • @vitiok78
      @vitiok78 6 місяців тому

      @@anthonygg_
      Just try this. Look how clean handlers are
      package main
      import (
      "context"
      "fmt"
      "net/http"
      )
      func main() {
      server := http.NewServeMux()
      server.HandleFunc("/", withError(handle))
      fmt.Println("Serving...")
      http.ListenAndServe(":8080", server)
      }
      func withError(next http.HandlerFunc) http.HandlerFunc {
      return func(w http.ResponseWriter, r *http.Request) {
      next(w, r)
      if errors, ok := r.Context().Value("errors").([]error); ok {
      for _, err := range errors {
      fmt.Println(err)
      }
      }
      }
      }
      func handle(w http.ResponseWriter, r *http.Request) {
      fmt.Fprint(w, "Hello, World from handler!")
      err := fmt.Errorf("error from handler")
      handleError(r, err)
      }
      func handle2(w http.ResponseWriter, r *http.Request) {
      fmt.Fprint(w, "Hello, World from handler2!")
      err := fmt.Errorf("error from handler2")
      handleError(r, err)
      }
      func handleError(r *http.Request, err error) {
      if err == nil {
      return
      }
      errors := []error{err}
      if errs, ok := r.Context().Value("errors").([]error); ok {
      errors = append(errs, err)
      }
      ctx := context.WithValue(r.Context(), "errors", errors)
      req := r.WithContext(ctx)
      *r = *req
      }

    • @h3ckphy246
      @h3ckphy246 3 місяці тому

      Англоговорящие не используют скобочки как смайлики)))) Спалился

  • @arenhovsepyan1463
    @arenhovsepyan1463 6 місяців тому +3

    Anthony all these lessons are great, but share with your music playlist man!!

  • @acheraime
    @acheraime 6 місяців тому +1

    That’s the reason why I love echo.

  • @carlosemiliovaldesvillegas9349
    @carlosemiliovaldesvillegas9349 6 місяців тому +1

    There always will be ego battles.
    I found a useful video. Thx!

  • @awesomedavid2012
    @awesomedavid2012 6 місяців тому

    Personally, now that I look at my prior code, the only thing I use the error return for is to do something like `return c.status...`. Essentially, so I can modify the context and then break control flow. Besides that, I haven't actually used the error return for explicit error handling.
    I suppose this may change if http itself returns an error but I would have to make an application with just http to determine if I actually care or not. I like the concept, but it may not be needed for me.

  • @CaptainDouchie
    @CaptainDouchie 6 місяців тому +1

    when is ur new go course coming out and how is it different from ur other go course?

    • @anthonygg_
      @anthonygg_  6 місяців тому

      Its out.

    • @CaptainDouchie
      @CaptainDouchie 6 місяців тому

      @@anthonygg_i don’t see the new templ go course

  • @matiasbpg
    @matiasbpg 6 місяців тому

    I agree that it would have been better if http.Handler had return error and with a error handler at mux level. That being said a framework, IMO is an over kill for something so easy to accomplish. It is less ergonomic to have middlewere everywhere, so probably y would use a single middlewere on the mux ( because the mix is s http.Handler) and pass errors though context ( or a custom context to make sure error accessing is type safe)

  • @bartukocakara7794
    @bartukocakara7794 6 місяців тому +1

    Hey Anthony what do you think about job opporunities in europe and usa between java and go ? Which one is worth to learn ?

    • @marcs8325
      @marcs8325 5 місяців тому

      Java probably has more job opportunities, but it doesn't mean a Java job is "Java only". You might end up coding in Kotlin, or even build a Go microservice. But it will be listed as a Java job, because Java is absolutely required to maintain a large part of the code base.
      Same goes for .NET. I'm a .NET developer, but I do write Python sometimes and I'm looking at Go as well.
      It will be much harder to find a "Go only" job, because the language is relatively new.
      I also work on code which is 20 years old 😂 Large companies have lots of legacy code and they're not going to rewrite it just for fun.

  • @SergioHerreroCruz96
    @SergioHerreroCruz96 6 місяців тому +1

    Awesome, thank you!

  • @dmitriykuvandikov5013
    @dmitriykuvandikov5013 6 місяців тому

    "Howto ruin primary argument of using gin/echo/whatever framework in 12 mins" from Antony :D

  • @theme3763
    @theme3763 6 місяців тому +1

    i make a function which is writejsonerror and writejson the jsonerror write the error and log error while writejson is for the responses to write the json successful response and solved no need for return to be clean

  • @maciekwojdyna2271
    @maciekwojdyna2271 2 місяці тому

    arjen robben is a real fucking engineer

  • @MarinescuEdward
    @MarinescuEdward 6 місяців тому

    Can you make video how to deploy golang apps wiht Github Actions

  • @assaidy
    @assaidy 2 місяці тому

    That was very nice.

  • @ТарасМалиновский-ф6ф
    @ТарасМалиновский-ф6ф 5 місяців тому

    RFS7807?

  • @cristophermoreno2290
    @cristophermoreno2290 6 місяців тому +1

    🔥🔥🔥 GIGACHAD

  • @pauloafpjunior
    @pauloafpjunior 6 місяців тому

    Very good.

  • @Akim-z8t
    @Akim-z8t 6 місяців тому

    Just use chi and chill (kidding, use echo or gin or gonet)

  • @mistart1633
    @mistart1633 6 місяців тому

    Thats a video for timmies

  • @NikolaPetkanski31337
    @NikolaPetkanski31337 6 місяців тому

    Having exceptions would render this approach useless.