func (rec recoverer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	reqID := gmiddleware.GetReqID(*rec.c)

	defer func() {
		if r := recover(); r != nil {
			var err error
			switch x := r.(type) {
			case error:
				err = x
			default:
				err = fmt.Errorf("%v", x)
			}
			rec.l.WithFields(logrus.Fields{
				"req_id": reqID,
				"method": req.Method,
				"uri":    req.RequestURI,
				"remote": req.RemoteAddr,
				"err":    err.Error(),
				"stack":  stack.Callers(0),
			}).Warn("service.err")
			http.Error(resp, http.StatusText(500), 500)
		}
	}()

	rec.h.ServeHTTP(resp, req)

}
Beispiel #2
0
// Get finds the name of test and the package from the stack, if possible, or tries its best otherwise.
func Get(id string) string {
	s := stack.Callers(1)

	for _, f := range s {
		if strings.HasSuffix(f.File, "_test.go") {
			var name string
			if strings.HasPrefix(f.Name, "Test") {
				name = f.Name
			} else if strings.HasSuffix(f.Name, "SetUpSuite") {
				name = "SetUpSuite"
			} else if strings.HasSuffix(f.Name, "SetUpTest") {
				name = "SetUpTest"
			}
			if name != "" {
				file := replacer.Replace(f.File)
				return fmt.Sprintf("%s_%s_", file, name)
			}
		}
	}

	// find the first caller outside ourselves
	outside := s[0].File
	for _, f := range s {
		if f.File != s[0].File {
			outside = f.Name
			break
		}
	}

	return fmt.Sprintf("TestNameNotFound_%s_%s_", id, outside)
}
Beispiel #3
0
// New returns a middleware that: recovers from panics, logs the panic and backtrace,
// writes a HTML response and Internal Server Error status.
//
// If a JSON content type is detected it returns a JSON response.
func New(opts *Options) func(h http.Handler) http.Handler {
	if opts == nil || opts.Log == nil {
		opts = &Options{Log: log.Print}
	}

	return func(h http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			defer func() {
				if err := recover(); err != nil {
					frames := stack.Callers(3)

					opts.Log(fmt.Sprintf(logFmt, titleClr("PANIC"), err, frames.String()))

					w.WriteHeader(http.StatusInternalServerError)

					ct := r.Header.Get(contentType)
					if strings.HasPrefix(ct, applicationJSON) {
						w.Header().Set(contentType, applicationJSONCharsetUTF8)

						e := jsonError{Message: err, Location: frames[0].String()}
						json.NewEncoder(w).Encode(e)
					} else {
						w.Write(compileTemplate(r, err, frames))
					}
				}
			}()
			h.ServeHTTP(w, r)
		}
		return http.HandlerFunc(fn)
	}
}
Beispiel #4
0
func (c *Client) errors(skip int, errs ...error) error {
	l := make([]Event, len(errs))
	for i, e := range errs {
		// we add one to skip because we want to skip errors() as well
		l[i] = convertError(e, stack.Callers(skip+1))
	}

	return c.Notify(l)
}
Beispiel #5
0
func (c cond) String() string {
	var b bytes.Buffer
	if c.DisableDeleteSelf {
		fmt.Fprint(&b, "\n")
	} else {
		fmt.Fprint(&b, deleteSelf)
	}
	fmt.Fprint(&b, pstack(stack.Callers(c.Skip+1), c.DisableDeleteSelf))
	if c.Format != "" {
		fmt.Fprintf(&b, c.Format, c.FormatArgs...)
	}
	if len(c.Extra) != 0 {
		fmt.Fprint(&b, "\n")
		fmt.Fprint(&b, tsdump(c.Extra...))
	}
	return b.String()
}
Beispiel #6
0
// WrapSkip may wrap the error and return an augmented error depending on the
// configuration in the context. The defaults result in the error being
// returned as is. It also handles nils correctly, returning a nil in that
// case. If the given error is already wrapped, it returns it as-is.
func WrapSkip(ctx context.Context, err error, skip int) error {
	switch err := err.(type) {
	case nil:
		return nil
	case *singleFrameError:
		return err
	case *singleStackError:
		return err
	case *multiStackError:
		err.multiStack.AddCallers(skip + 1)
		return err
	}

	config := ContextConfig(ctx)
	switch config.StackMode {
	case StackModeSingleFrame:
		return &singleFrameError{
			config:     config,
			underlying: err,
			frame:      stack.Caller(skip + 1),
		}
	case StackModeSingleStack:
		return &singleStackError{
			config:     config,
			underlying: err,
			stack:      stack.Callers(skip + 1),
		}
	case StackModeMultiStack:
		return &multiStackError{
			config:     config,
			underlying: err,
			multiStack: stack.CallersMulti(skip + 1),
		}
	}
	return err
}
Beispiel #7
0
func (m typ) indirect1() stack.Stack {
	return stack.Callers(0)
}
Beispiel #8
0
func BenchmarkCallers(b *testing.B) {
	for i := 0; i < b.N; i++ {
		stack.Callers(0)
	}
}