summaryrefslogtreecommitdiffhomepage
path: root/middleware/errors
diff options
context:
space:
mode:
authorMatthew Holt <[email protected]>2015-05-05 15:48:10 -0600
committerMatthew Holt <[email protected]>2015-05-05 15:48:10 -0600
commit857b4f90d9c99531ecbcc371f475b4da728689b7 (patch)
tree2524b0daf296df033954cc20114ef9355500fca8 /middleware/errors
parent97e702b9638c358eb4b2cd16bb67d36d36f6dabb (diff)
downloadcaddy-857b4f90d9c99531ecbcc371f475b4da728689b7.tar.gz
caddy-857b4f90d9c99531ecbcc371f475b4da728689b7.zip
errors: Log includes file and line number of panics
Diffstat (limited to 'middleware/errors')
-rw-r--r--middleware/errors/errors.go45
1 files changed, 39 insertions, 6 deletions
diff --git a/middleware/errors/errors.go b/middleware/errors/errors.go
index e1c03e644..ce9a7cd83 100644
--- a/middleware/errors/errors.go
+++ b/middleware/errors/errors.go
@@ -7,6 +7,8 @@ import (
"log"
"net/http"
"os"
+ "runtime"
+ "strings"
"github.com/mholt/caddy/middleware"
)
@@ -20,12 +22,7 @@ type ErrorHandler struct {
}
func (h ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
- defer func() {
- if rec := recover(); rec != nil {
- h.Log.Printf("[PANIC %s] %v", r.URL.String(), rec)
- h.errorPage(w, http.StatusInternalServerError)
- }
- }()
+ defer h.recovery(w, r)
status, err := h.Next.ServeHTTP(w, r)
@@ -78,4 +75,40 @@ func (h ErrorHandler) errorPage(w http.ResponseWriter, code int) {
http.Error(w, defaultBody, code)
}
+func (h ErrorHandler) recovery(w http.ResponseWriter, r *http.Request) {
+ rec := recover()
+ if rec == nil {
+ return
+ }
+
+ // Obtain source of panic
+ // From: https://gist.github.com/swdunlop/9629168
+ var name, file string // function name, file name
+ var line int
+ var pc [16]uintptr
+ n := runtime.Callers(3, pc[:])
+ for _, pc := range pc[:n] {
+ fn := runtime.FuncForPC(pc)
+ if fn == nil {
+ continue
+ }
+ file, line = fn.FileLine(pc)
+ name = fn.Name()
+ if !strings.HasPrefix(name, "runtime.") {
+ break
+ }
+ }
+
+ // Trim file path
+ delim := "/caddy/"
+ pkgPathPos := strings.Index(file, delim)
+ if pkgPathPos > -1 && len(file) > pkgPathPos+len(delim) {
+ file = file[pkgPathPos+len(delim):]
+ }
+
+ // Currently we don't use the function name, as file:line is more conventional
+ h.Log.Printf("[PANIC %s] %s:%d - %v", r.URL.String(), file, line, rec)
+ h.errorPage(w, http.StatusInternalServerError)
+}
+
const DefaultLogFilename = "error.log"