Initial euclide.org release
This commit is contained in:
91
vendor/github.com/jarcoal/httpmock/internal/stack_tracer.go
generated
vendored
Normal file
91
vendor/github.com/jarcoal/httpmock/internal/stack_tracer.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type StackTracer struct {
|
||||
CustomFn func(...interface{})
|
||||
Err error
|
||||
}
|
||||
|
||||
// Error implements error interface.
|
||||
func (s StackTracer) Error() string {
|
||||
if s.Err == nil {
|
||||
return ""
|
||||
}
|
||||
return s.Err.Error()
|
||||
}
|
||||
|
||||
// Unwrap implements the interface needed by errors.Unwrap.
|
||||
func (s StackTracer) Unwrap() error {
|
||||
return s.Err
|
||||
}
|
||||
|
||||
// CheckStackTracer checks for specific error returned by
|
||||
// NewNotFoundResponder function or Trace Responder method.
|
||||
func CheckStackTracer(req *http.Request, err error) error {
|
||||
if nf, ok := err.(StackTracer); ok {
|
||||
if nf.CustomFn != nil {
|
||||
pc := make([]uintptr, 128)
|
||||
npc := runtime.Callers(2, pc)
|
||||
pc = pc[:npc]
|
||||
|
||||
var mesg bytes.Buffer
|
||||
var netHTTPBegin, netHTTPEnd bool
|
||||
|
||||
// Start recording at first net/http call if any...
|
||||
for {
|
||||
frames := runtime.CallersFrames(pc)
|
||||
|
||||
var lastFn string
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
|
||||
if !netHTTPEnd {
|
||||
if netHTTPBegin {
|
||||
netHTTPEnd = !strings.HasPrefix(frame.Function, "net/http.")
|
||||
} else {
|
||||
netHTTPBegin = strings.HasPrefix(frame.Function, "net/http.")
|
||||
}
|
||||
}
|
||||
|
||||
if netHTTPEnd {
|
||||
if lastFn != "" {
|
||||
if mesg.Len() == 0 {
|
||||
if nf.Err != nil {
|
||||
mesg.WriteString(nf.Err.Error())
|
||||
} else {
|
||||
fmt.Fprintf(&mesg, "%s %s", req.Method, req.URL)
|
||||
}
|
||||
mesg.WriteString("\nCalled from ")
|
||||
} else {
|
||||
mesg.WriteString("\n ")
|
||||
}
|
||||
fmt.Fprintf(&mesg, "%s()\n at %s:%d", lastFn, frame.File, frame.Line)
|
||||
}
|
||||
}
|
||||
lastFn = frame.Function
|
||||
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// At least one net/http frame found
|
||||
if mesg.Len() > 0 {
|
||||
break
|
||||
}
|
||||
netHTTPEnd = true // retry without looking at net/http frames
|
||||
}
|
||||
|
||||
nf.CustomFn(mesg.String())
|
||||
}
|
||||
err = nf.Err
|
||||
}
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user