Skip to content

Instantly share code, notes, and snippets.

@amitsaha
Last active July 16, 2021 23:13
Show Gist options
  • Save amitsaha/ec7ce96e47bbfca0e7a52d5bff53485b to your computer and use it in GitHub Desktop.
Save amitsaha/ec7ce96e47bbfca0e7a52d5bff53485b to your computer and use it in GitHub Desktop.

Revisions

  1. amitsaha revised this gist Jul 16, 2021. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions doc.md
    Original file line number Diff line number Diff line change
    @@ -71,3 +71,8 @@ func (c *conn) serve(ctx context.Context) {
    However, when I make a request to the /2 endpoint, there is no log of the panic as explained by the documentation
    of `ErrAbortHandler`.

    Due to the recovery mechanism setup, the server process doesn't get aborted and the panic details are logged.

    You can also write a middleware to setup your own recovery mechanism so that the stdlib's recovery mechanism is not
    triggered at all.

  2. amitsaha revised this gist Jul 16, 2021. 2 changed files with 26 additions and 20 deletions.
    26 changes: 26 additions & 0 deletions comments.md → doc.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,28 @@
    Consider a test HTTP server in Go:

    ```
    package main
    import "net/http"
    func myHandler1(w http.ResponseWriter, r *http.Request) {
    panic("I panicked")
    }
    func myHandler2(w http.ResponseWriter, r *http.Request) {
    panic(http.ErrAbortHandler)
    }
    func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/1", myHandler1)
    mux.HandleFunc("/2", myHandler2)
    http.ListenAndServe(":8080", mux)
    }
    ```

    When i make a request to the /1 endpoint, on the server i see this:

    ```
    @@ -45,3 +70,4 @@ func (c *conn) serve(ctx context.Context) {

    However, when I make a request to the /2 endpoint, there is no log of the panic as explained by the documentation
    of `ErrAbortHandler`.

    20 changes: 0 additions & 20 deletions main.go
    Original file line number Diff line number Diff line change
    @@ -1,20 +0,0 @@
    package main

    import "net/http"

    func myHandler1(w http.ResponseWriter, r *http.Request) {
    panic("I panicked")
    }

    func myHandler2(w http.ResponseWriter, r *http.Request) {
    panic(http.ErrAbortHandler)
    }

    func main() {

    mux := http.NewServeMux()
    mux.HandleFunc("/1", myHandler1)
    mux.HandleFunc("/2", myHandler2)

    http.ListenAndServe(":8080", mux)
    }
  3. amitsaha created this gist Jul 16, 2021.
    47 changes: 47 additions & 0 deletions comments.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    When i make a request to the /1 endpoint, on the server i see this:

    ```
    2021/07/17 09:04:07 http: panic serving [::1]:52336: I panicked
    goroutine 4 [running]:
    net/http.(*conn).serve.func1(0x1400010aa00)
    /usr/local/go/src/net/http/server.go:1824 +0x108
    panic(0x102672ca0, 0x1026c3590)
    /usr/local/go/src/runtime/panic.go:971 +0x3f4
    main.myHandler1(0x1026cbb30, 0x140001420e0, 0x1400014e000)
    /Users/echorand/work/github.com/amitsaha/tmp/server.go:6 +0x38
    net/http.HandlerFunc.ServeHTTP(0x1026c2790, 0x1026cbb30, 0x140001420e0, 0x1400014e000)
    /usr/local/go/src/net/http/server.go:2069 +0x40
    net/http.(*ServeMux).ServeHTTP(0x14000024200, 0x1026cbb30, 0x140001420e0, 0x1400014e000)
    /usr/local/go/src/net/http/server.go:2448 +0x190
    net/http.serverHandler.ServeHTTP(0x14000142000, 0x1026cbb30, 0x140001420e0, 0x1400014e000)
    /usr/local/go/src/net/http/server.go:2887 +0xbc
    net/http.(*conn).serve(0x1400010aa00, 0x1026cc000, 0x14000024280)
    /usr/local/go/src/net/http/server.go:1952 +0x710
    created by net/http.(*Server).Serve
    /usr/local/go/src/net/http/server.go:3013 +0x308
    ```

    The recovery is happening here in the stdlib's [code](https://golang.org/src/net/http/server.go?s=99233:99288#L1797):

    ```
    // Serve a new connection.
    func (c *conn) serve(ctx context.Context) {
    c.remoteAddr = c.rwc.RemoteAddr().String()
    ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
    defer func() {
    if err := recover(); err != nil && err != ErrAbortHandler {
    const size = 64 << 10
    buf := make([]byte, size)
    buf = buf[:runtime.Stack(buf, false)]
    c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
    }
    if !c.hijacked() {
    c.close()
    c.setState(c.rwc, StateClosed, runHooks)
    }
    }()
    ```

    However, when I make a request to the /2 endpoint, there is no log of the panic as explained by the documentation
    of `ErrAbortHandler`.
    20 changes: 20 additions & 0 deletions main.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    package main

    import "net/http"

    func myHandler1(w http.ResponseWriter, r *http.Request) {
    panic("I panicked")
    }

    func myHandler2(w http.ResponseWriter, r *http.Request) {
    panic(http.ErrAbortHandler)
    }

    func main() {

    mux := http.NewServeMux()
    mux.HandleFunc("/1", myHandler1)
    mux.HandleFunc("/2", myHandler2)

    http.ListenAndServe(":8080", mux)
    }