github.com/zak-blake/goa@v1.4.1/middleware/recover.go (about)

     1  package middleware
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"runtime"
     7  	"strings"
     8  
     9  	"github.com/goadesign/goa"
    10  
    11  	"context"
    12  )
    13  
    14  // Recover is a middleware that recovers panics and maps them to errors.
    15  func Recover() goa.Middleware {
    16  	return func(h goa.Handler) goa.Handler {
    17  		return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) (err error) {
    18  			defer func() {
    19  				if r := recover(); r != nil {
    20  					var msg string
    21  					switch x := r.(type) {
    22  					case string:
    23  						msg = fmt.Sprintf("panic: %s", x)
    24  					case error:
    25  						msg = fmt.Sprintf("panic: %s", x)
    26  					default:
    27  						msg = "unknown panic"
    28  					}
    29  					const size = 64 << 10 // 64KB
    30  					buf := make([]byte, size)
    31  					buf = buf[:runtime.Stack(buf, false)]
    32  					lines := strings.Split(string(buf), "\n")
    33  					stack := lines[3:]
    34  					err = fmt.Errorf("%s\n%s", msg, strings.Join(stack, "\n"))
    35  				}
    36  			}()
    37  			return h(ctx, rw, req)
    38  		}
    39  	}
    40  }