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.

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