codes.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package codes // import "go.opentelemetry.io/otel/codes"
  4. import (
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "strconv"
  9. )
  10. const (
  11. // Unset is the default status code.
  12. Unset Code = 0
  13. // Error indicates the operation contains an error.
  14. //
  15. // NOTE: The error code in OTLP is 2.
  16. // The value of this enum is only relevant to the internals
  17. // of the Go SDK.
  18. Error Code = 1
  19. // Ok indicates operation has been validated by an Application developers
  20. // or Operator to have completed successfully, or contain no error.
  21. //
  22. // NOTE: The Ok code in OTLP is 1.
  23. // The value of this enum is only relevant to the internals
  24. // of the Go SDK.
  25. Ok Code = 2
  26. maxCode = 3
  27. )
  28. // Code is an 32-bit representation of a status state.
  29. type Code uint32
  30. var codeToStr = map[Code]string{
  31. Unset: "Unset",
  32. Error: "Error",
  33. Ok: "Ok",
  34. }
  35. var strToCode = map[string]Code{
  36. `"Unset"`: Unset,
  37. `"Error"`: Error,
  38. `"Ok"`: Ok,
  39. }
  40. // String returns the Code as a string.
  41. func (c Code) String() string {
  42. return codeToStr[c]
  43. }
  44. // UnmarshalJSON unmarshals b into the Code.
  45. //
  46. // This is based on the functionality in the gRPC codes package:
  47. // https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244
  48. func (c *Code) UnmarshalJSON(b []byte) error {
  49. // From json.Unmarshaler: By convention, to approximate the behavior of
  50. // Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as
  51. // a no-op.
  52. if string(b) == "null" {
  53. return nil
  54. }
  55. if c == nil {
  56. return errors.New("nil receiver passed to UnmarshalJSON")
  57. }
  58. var x any
  59. if err := json.Unmarshal(b, &x); err != nil {
  60. return err
  61. }
  62. switch x.(type) {
  63. case string:
  64. if jc, ok := strToCode[string(b)]; ok {
  65. *c = jc
  66. return nil
  67. }
  68. return fmt.Errorf("invalid code: %q", string(b))
  69. case float64:
  70. if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
  71. if ci >= maxCode {
  72. return fmt.Errorf("invalid code: %q", ci)
  73. }
  74. *c = Code(ci) // nolint: gosec // Bit size of 32 check above.
  75. return nil
  76. }
  77. return fmt.Errorf("invalid code: %q", string(b))
  78. default:
  79. return fmt.Errorf("invalid code: %q", string(b))
  80. }
  81. }
  82. // MarshalJSON returns c as the JSON encoding of c.
  83. func (c *Code) MarshalJSON() ([]byte, error) {
  84. if c == nil {
  85. return []byte("null"), nil
  86. }
  87. str, ok := codeToStr[*c]
  88. if !ok {
  89. return nil, fmt.Errorf("invalid code: %d", *c)
  90. }
  91. return fmt.Appendf(nil, "%q", str), nil
  92. }