add an error context

This commit is contained in:
Rick Olson 2014-08-08 11:05:24 -06:00
parent beccfaa9f6
commit 890a42cd68
3 changed files with 44 additions and 6 deletions

@ -141,6 +141,9 @@ func logPanic(loggedError error, recursive bool) string {
if wErr, ok := loggedError.(ErrorWithStack); ok {
fmt.Fprintln(fmtWriter, wErr.InnerError())
for key, value := range wErr.Context() {
fmt.Fprintf(fmtWriter, "%s=%s\n", key, value)
}
fmtWriter.Write(wErr.Stack())
} else {
fmtWriter.Write(gitmedia.Stack())
@ -155,6 +158,7 @@ func logPanic(loggedError error, recursive bool) string {
}
type ErrorWithStack interface {
Context() map[string]string
InnerError() string
Stack() []byte
}

@ -9,6 +9,7 @@ type WrappedError struct {
Err error
Message string
stack []byte
context map[string]string
}
func Error(err error) *WrappedError {
@ -33,6 +34,27 @@ func Errorf(err error, format string, args ...interface{}) *WrappedError {
return e
}
func (e *WrappedError) Set(key, value string) {
if e.context == nil {
e.context = make(map[string]string)
}
e.context[key] = value
}
func (e *WrappedError) Get(key string) string {
if e.context == nil {
return ""
}
return e.context[key]
}
func (e *WrappedError) Del(key string) {
if e.context == nil {
return
}
delete(e.context, key)
}
func (e *WrappedError) Error() string {
return e.Message
}
@ -49,6 +71,13 @@ func (e *WrappedError) Stack() []byte {
return e.stack
}
func (e *WrappedError) Context() map[string]string {
if e.context == nil {
e.context = make(map[string]string)
}
return e.context
}
func Stack() []byte {
stackBuf := make([]byte, 1024*1024)
written := runtime.Stack(stackBuf, false)

@ -98,10 +98,10 @@ func Get(filename string) (io.ReadCloser, int64, *gitmedia.WrappedError) {
}
req.Header.Set("Accept", gitMediaType)
res, err := doRequest(req, creds)
res, wErr := doRequest(req, creds)
if err != nil {
return nil, 0, gitmedia.Error(err)
return nil, 0, wErr
}
contentType := res.Header.Get("Content-Type")
@ -146,7 +146,7 @@ func validateMediaHeader(contentType string, reader io.Reader) (bool, error) {
return true, nil
}
func doRequest(req *http.Request, creds Creds) (*http.Response, error) {
func doRequest(req *http.Request, creds Creds) (*http.Response, *gitmedia.WrappedError) {
res, err := http.DefaultClient.Do(req)
if err == nil {
@ -159,16 +159,21 @@ func doRequest(req *http.Request, creds Creds) (*http.Response, error) {
apierr := &Error{}
dec := json.NewDecoder(res.Body)
if err := dec.Decode(apierr); err != nil {
return res, err
return res, gitmedia.Errorf(err, "Error decoding JSON from response")
}
return res, apierr
return res, gitmedia.Errorf(apierr, "Invalid response: %d", res.StatusCode)
}
execCreds(creds, "approve")
}
return res, err
wErr := gitmedia.Errorf(err, "Error sending HTTP request to %s", req.URL.String())
wErr.Set("URL", req.URL.String())
for key, _ := range req.Header {
wErr.Set(key, req.Header.Get(key))
}
return res, wErr
}
func clientRequest(method, oid string) (*http.Request, Creds, error) {