errors.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package errors implements functions to manipulate errors.
  5. package errors
  6. import (
  7. "errors"
  8. "fmt"
  9. "google.golang.org/protobuf/internal/detrand"
  10. )
  11. // Error is a sentinel matching all errors produced by this package.
  12. var Error = errors.New("protobuf error")
  13. // New formats a string according to the format specifier and arguments and
  14. // returns an error that has a "proto" prefix.
  15. func New(f string, x ...interface{}) error {
  16. return &prefixError{s: format(f, x...)}
  17. }
  18. type prefixError struct{ s string }
  19. var prefix = func() string {
  20. // Deliberately introduce instability into the error message string to
  21. // discourage users from performing error string comparisons.
  22. if detrand.Bool() {
  23. return "proto: " // use non-breaking spaces (U+00a0)
  24. } else {
  25. return "proto: " // use regular spaces (U+0020)
  26. }
  27. }()
  28. func (e *prefixError) Error() string {
  29. return prefix + e.s
  30. }
  31. func (e *prefixError) Unwrap() error {
  32. return Error
  33. }
  34. // Wrap returns an error that has a "proto" prefix, the formatted string described
  35. // by the format specifier and arguments, and a suffix of err. The error wraps err.
  36. func Wrap(err error, f string, x ...interface{}) error {
  37. return &wrapError{
  38. s: format(f, x...),
  39. err: err,
  40. }
  41. }
  42. type wrapError struct {
  43. s string
  44. err error
  45. }
  46. func (e *wrapError) Error() string {
  47. return format("%v%v: %v", prefix, e.s, e.err)
  48. }
  49. func (e *wrapError) Unwrap() error {
  50. return e.err
  51. }
  52. func (e *wrapError) Is(target error) bool {
  53. return target == Error
  54. }
  55. func format(f string, x ...interface{}) string {
  56. // avoid "proto: " prefix when chaining
  57. for i := 0; i < len(x); i++ {
  58. switch e := x[i].(type) {
  59. case *prefixError:
  60. x[i] = e.s
  61. case *wrapError:
  62. x[i] = format("%v: %v", e.s, e.err)
  63. }
  64. }
  65. return fmt.Sprintf(f, x...)
  66. }
  67. func InvalidUTF8(name string) error {
  68. return New("field %v contains invalid UTF-8", name)
  69. }
  70. func RequiredNotSet(name string) error {
  71. return New("required field %v not set", name)
  72. }