You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.2 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package common
  2. import (
  3. "fmt"
  4. "runtime"
  5. )
  6. //----------------------------------------
  7. // Error & cmnError
  8. type Error interface {
  9. Error() string
  10. Trace(format string, a ...interface{}) Error
  11. TraceCause(cause error, format string, a ...interface{}) Error
  12. Cause() error
  13. Type() interface{}
  14. WithType(t interface{}) Error
  15. }
  16. // New Error with no cause where the type is the format string of the message..
  17. func NewError(format string, a ...interface{}) Error {
  18. msg := Fmt(format, a...)
  19. return newError(msg, nil, format)
  20. }
  21. // New Error with cause where the type is the cause, with message..
  22. func NewErrorWithCause(cause error, format string, a ...interface{}) Error {
  23. msg := Fmt(format, a...)
  24. return newError(msg, cause, cause)
  25. }
  26. // New Error with specified type and message.
  27. func NewErrorWithType(type_ interface{}, format string, a ...interface{}) Error {
  28. msg := Fmt(format, a...)
  29. return newError(msg, nil, type_)
  30. }
  31. type traceItem struct {
  32. msg string
  33. filename string
  34. lineno int
  35. }
  36. func (ti traceItem) String() string {
  37. return fmt.Sprintf("%v:%v %v", ti.filename, ti.lineno, ti.msg)
  38. }
  39. type cmnError struct {
  40. msg string
  41. cause error
  42. type_ interface{}
  43. traces []traceItem
  44. }
  45. // NOTE: Do not expose, it's not very friendly.
  46. func newError(msg string, cause error, type_ interface{}) *cmnError {
  47. return &cmnError{
  48. msg: msg,
  49. cause: cause,
  50. type_: type_,
  51. traces: nil,
  52. }
  53. }
  54. func (err *cmnError) Error() string {
  55. return fmt.Sprintf("Error{%v:%s,%v,%v}", err.type_, err.msg, err.cause, len(err.traces))
  56. }
  57. // Add tracing information with msg.
  58. func (err *cmnError) Trace(format string, a ...interface{}) Error {
  59. msg := Fmt(format, a...)
  60. return err.doTrace(msg, 2)
  61. }
  62. // Add tracing information with cause and msg.
  63. // If a cause was already set before, it is overwritten.
  64. func (err *cmnError) TraceCause(cause error, format string, a ...interface{}) Error {
  65. msg := Fmt(format, a...)
  66. err.cause = cause
  67. return err.doTrace(msg, 2)
  68. }
  69. // Return the "type" of this message, primarily for switching
  70. // to handle this error.
  71. func (err *cmnError) Type() interface{} {
  72. return err.type_
  73. }
  74. // Overwrites the error's type.
  75. func (err *cmnError) WithType(type_ interface{}) Error {
  76. err.type_ = type_
  77. return err
  78. }
  79. func (err *cmnError) doTrace(msg string, n int) Error {
  80. _, fn, line, ok := runtime.Caller(n)
  81. if !ok {
  82. if fn == "" {
  83. fn = "<unknown>"
  84. }
  85. if line <= 0 {
  86. line = -1
  87. }
  88. }
  89. // Include file & line number & msg.
  90. // Do not include the whole stack trace.
  91. err.traces = append(err.traces, traceItem{
  92. filename: fn,
  93. lineno: line,
  94. msg: msg,
  95. })
  96. return err
  97. }
  98. // Return last known cause.
  99. // NOTE: The meaning of "cause" is left for the caller to define.
  100. // There exists to canonical definition of "cause".
  101. // Instead of blaming, try to handle-or-organize it.
  102. func (err *cmnError) Cause() error {
  103. return err.cause
  104. }
  105. //----------------------------------------
  106. // StackError
  107. // NOTE: Used by Tendermint p2p upon recovery.
  108. // Err could be "Reason", since it isn't an error type.
  109. type StackError struct {
  110. Err interface{}
  111. Stack []byte
  112. }
  113. func (se StackError) String() string {
  114. return fmt.Sprintf("Error: %v\nStack: %s", se.Err, se.Stack)
  115. }
  116. func (se StackError) Error() string {
  117. return se.String()
  118. }
  119. //----------------------------------------
  120. // Panic wrappers
  121. // XXX DEPRECATED
  122. // A panic resulting from a sanity check means there is a programmer error
  123. // and some guarantee is not satisfied.
  124. // XXX DEPRECATED
  125. func PanicSanity(v interface{}) {
  126. panic(Fmt("Panicked on a Sanity Check: %v", v))
  127. }
  128. // A panic here means something has gone horribly wrong, in the form of data corruption or
  129. // failure of the operating system. In a correct/healthy system, these should never fire.
  130. // If they do, it's indicative of a much more serious problem.
  131. // XXX DEPRECATED
  132. func PanicCrisis(v interface{}) {
  133. panic(Fmt("Panicked on a Crisis: %v", v))
  134. }
  135. // Indicates a failure of consensus. Someone was malicious or something has
  136. // gone horribly wrong. These should really boot us into an "emergency-recover" mode
  137. // XXX DEPRECATED
  138. func PanicConsensus(v interface{}) {
  139. panic(Fmt("Panicked on a Consensus Failure: %v", v))
  140. }
  141. // For those times when we're not sure if we should panic
  142. // XXX DEPRECATED
  143. func PanicQ(v interface{}) {
  144. panic(Fmt("Panicked questionably: %v", v))
  145. }