errors.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package netlink
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "os"
  7. "strings"
  8. )
  9. // Error messages which can be returned by Validate.
  10. var (
  11. errMismatchedSequence = errors.New("mismatched sequence in netlink reply")
  12. errMismatchedPID = errors.New("mismatched PID in netlink reply")
  13. errShortErrorMessage = errors.New("not enough data for netlink error code")
  14. )
  15. // Errors which can be returned by a Socket that does not implement
  16. // all exposed methods of Conn.
  17. var errNotSupported = errors.New("operation not supported")
  18. // notSupported provides a concise constructor for "not supported" errors.
  19. func notSupported(op string) error {
  20. return newOpError(op, errNotSupported)
  21. }
  22. // IsNotExist determines if an error is produced as the result of querying some
  23. // file, object, resource, etc. which does not exist.
  24. //
  25. // Deprecated: use errors.Unwrap and/or `errors.Is(err, os.Permission)` in Go
  26. // 1.13+.
  27. func IsNotExist(err error) bool {
  28. switch err := err.(type) {
  29. case *OpError:
  30. // Unwrap the inner error and use the stdlib's logic.
  31. return os.IsNotExist(err.Err)
  32. default:
  33. return os.IsNotExist(err)
  34. }
  35. }
  36. var (
  37. _ error = &OpError{}
  38. _ net.Error = &OpError{}
  39. // Ensure compatibility with Go 1.13+ errors package.
  40. _ interface{ Unwrap() error } = &OpError{}
  41. )
  42. // An OpError is an error produced as the result of a failed netlink operation.
  43. type OpError struct {
  44. // Op is the operation which caused this OpError, such as "send"
  45. // or "receive".
  46. Op string
  47. // Err is the underlying error which caused this OpError.
  48. //
  49. // If Err was produced by a system call error, Err will be of type
  50. // *os.SyscallError. If Err was produced by an error code in a netlink
  51. // message, Err will contain a raw error value type such as a unix.Errno.
  52. //
  53. // Most callers should inspect Err using errors.Is from the standard
  54. // library.
  55. Err error
  56. // Message and Offset contain additional error information provided by the
  57. // kernel when the ExtendedAcknowledge option is set on a Conn and the
  58. // kernel indicates the AcknowledgeTLVs flag in a response. If this option
  59. // is not set, both of these fields will be empty.
  60. Message string
  61. Offset int
  62. }
  63. // newOpError is a small wrapper for creating an OpError. As a convenience, it
  64. // returns nil if the input err is nil: akin to os.NewSyscallError.
  65. func newOpError(op string, err error) error {
  66. if err == nil {
  67. return nil
  68. }
  69. return &OpError{
  70. Op: op,
  71. Err: err,
  72. }
  73. }
  74. func (e *OpError) Error() string {
  75. if e == nil {
  76. return "<nil>"
  77. }
  78. var sb strings.Builder
  79. _, _ = sb.WriteString(fmt.Sprintf("netlink %s: %v", e.Op, e.Err))
  80. if e.Message != "" || e.Offset != 0 {
  81. _, _ = sb.WriteString(fmt.Sprintf(", offset: %d, message: %q",
  82. e.Offset, e.Message))
  83. }
  84. return sb.String()
  85. }
  86. // Unwrap unwraps the internal Err field for use with errors.Unwrap.
  87. func (e *OpError) Unwrap() error { return e.Err }
  88. // Portions of this code taken from the Go standard library:
  89. //
  90. // Copyright 2009 The Go Authors. All rights reserved.
  91. // Use of this source code is governed by a BSD-style
  92. // license that can be found in the LICENSE file.
  93. type timeout interface {
  94. Timeout() bool
  95. }
  96. // Timeout reports whether the error was caused by an I/O timeout.
  97. func (e *OpError) Timeout() bool {
  98. if ne, ok := e.Err.(*os.SyscallError); ok {
  99. t, ok := ne.Err.(timeout)
  100. return ok && t.Timeout()
  101. }
  102. t, ok := e.Err.(timeout)
  103. return ok && t.Timeout()
  104. }
  105. type temporary interface {
  106. Temporary() bool
  107. }
  108. // Temporary reports whether an operation may succeed if retried.
  109. func (e *OpError) Temporary() bool {
  110. if ne, ok := e.Err.(*os.SyscallError); ok {
  111. t, ok := ne.Err.(temporary)
  112. return ok && t.Temporary()
  113. }
  114. t, ok := e.Err.(temporary)
  115. return ok && t.Temporary()
  116. }