code: func Details(e error) string {
  	if e == nil {
  		return ""
  	}
  	msg := Message(e)
  
  	detailsLock.Lock()
  
  	var dets []string
  	for label, key := range detailFields {
  		v := Value(e, key)
  		if v != nil {
  			dets = append(dets, fmt.Sprintf("%s: %v", label, v))
  		}
  	}
  
  	detailsLock.Unlock()
  	if len(dets) > 0 {
  		// sort so output is predictable
  		sort.Strings(dets)
  		msg += "\n" + strings.Join(dets, "\n")
  	}
  
  	//userMsg := UserMessage(e)
  	//if userMsg != "" {
  	//	msg = fmt.Sprintf("%s\n\nUser Message: %s", msg, userMsg)
  	//}
  	s := Stacktrace(e)
  	if s != "" {
  		msg += "\n\n" + s
  	}
  
  	if c := Cause(e); c != nil {
  		msg += "\n\nCaused By: " + Details(c)
  	}
  	return msg
  }
docs: // Details returns e.Error(), e's stacktrace, and any additional details which have
  // be registered with RegisterDetail.  User message and HTTP code are already registered.
  //
  // The details of each error in e's cause chain will also be printed.