generic_error.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package libcontainer
  2. import (
  3. "fmt"
  4. "io"
  5. "text/template"
  6. "time"
  7. "github.com/opencontainers/runc/libcontainer/stacktrace"
  8. )
  9. var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}}
  10. Code: {{.ECode}}
  11. {{if .Message }}
  12. Message: {{.Message}}
  13. {{end}}
  14. Frames:{{range $i, $frame := .Stack.Frames}}
  15. ---
  16. {{$i}}: {{$frame.Function}}
  17. Package: {{$frame.Package}}
  18. File: {{$frame.File}}@{{$frame.Line}}{{end}}
  19. `))
  20. func newGenericError(err error, c ErrorCode) Error {
  21. if le, ok := err.(Error); ok {
  22. return le
  23. }
  24. gerr := &genericError{
  25. Timestamp: time.Now(),
  26. Err: err,
  27. ECode: c,
  28. Stack: stacktrace.Capture(1),
  29. }
  30. if err != nil {
  31. gerr.Message = err.Error()
  32. }
  33. return gerr
  34. }
  35. func newSystemError(err error) Error {
  36. return createSystemError(err, "")
  37. }
  38. func newSystemErrorWithCausef(err error, cause string, v ...interface{}) Error {
  39. return createSystemError(err, fmt.Sprintf(cause, v...))
  40. }
  41. func newSystemErrorWithCause(err error, cause string) Error {
  42. return createSystemError(err, cause)
  43. }
  44. // createSystemError creates the specified error with the correct number of
  45. // stack frames skipped. This is only to be called by the other functions for
  46. // formatting the error.
  47. func createSystemError(err error, cause string) Error {
  48. gerr := &genericError{
  49. Timestamp: time.Now(),
  50. Err: err,
  51. ECode: SystemError,
  52. Cause: cause,
  53. Stack: stacktrace.Capture(2),
  54. }
  55. if err != nil {
  56. gerr.Message = err.Error()
  57. }
  58. return gerr
  59. }
  60. type genericError struct {
  61. Timestamp time.Time
  62. ECode ErrorCode
  63. Err error `json:"-"`
  64. Cause string
  65. Message string
  66. Stack stacktrace.Stacktrace
  67. }
  68. func (e *genericError) Error() string {
  69. if e.Cause == "" {
  70. return e.Message
  71. }
  72. frame := e.Stack.Frames[0]
  73. return fmt.Sprintf("%s:%d: %s caused %q", frame.File, frame.Line, e.Cause, e.Message)
  74. }
  75. func (e *genericError) Code() ErrorCode {
  76. return e.ECode
  77. }
  78. func (e *genericError) Detail(w io.Writer) error {
  79. return errorTemplate.Execute(w, e)
  80. }