errors.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Package config provides configuration management functionality
  2. package config
  3. import (
  4. "errors"
  5. "fmt"
  6. )
  7. // Common config error types
  8. var (
  9. // ErrFileNotFound indicates the config file does not exist
  10. ErrFileNotFound = errors.New("config file not found")
  11. // ErrFilePermission indicates permission issues with the config file
  12. ErrFilePermission = errors.New("insufficient permissions for config file")
  13. // ErrInvalidYAML indicates YAML parsing or syntax errors
  14. ErrInvalidYAML = errors.New("invalid YAML format")
  15. // ErrMissingRequired indicates a required field is missing
  16. ErrMissingRequired = errors.New("missing required field")
  17. // ErrInvalidValue indicates a field has an invalid value
  18. ErrInvalidValue = errors.New("invalid field value")
  19. // ErrInvalidSection indicates an invalid or missing config section
  20. ErrInvalidSection = errors.New("invalid config section")
  21. // ErrValidationFailed indicates config validation failure
  22. ErrValidationFailed = errors.New("config validation failed")
  23. // ErrInvalidAppName indicates an invalid application name
  24. ErrInvalidAppName = errors.New("invalid application name")
  25. // ErrInvalidEnvironment indicates an invalid environment
  26. ErrInvalidEnvironment = errors.New("invalid environment")
  27. )
  28. // Error represents a configuration-specific error with detailed context
  29. type Error struct {
  30. // Op is the operation that failed (e.g., "read", "parse", "validate")
  31. Op string
  32. // Section is the config section involved (if applicable)
  33. Section string
  34. // Field is the specific field involved (if applicable)
  35. Field string
  36. // Value is the invalid value (if applicable)
  37. Value string
  38. // Err is the underlying error
  39. Err error
  40. // Details contains additional error context
  41. Details string
  42. }
  43. // Error returns a string representation of the error
  44. func (e *Error) Error() string {
  45. msg := fmt.Sprintf("config %s failed", e.Op)
  46. if e.Section != "" {
  47. msg = fmt.Sprintf("%s in section %q", msg, e.Section)
  48. }
  49. if e.Field != "" {
  50. msg = fmt.Sprintf("%s at field %q", msg, e.Field)
  51. }
  52. if e.Value != "" {
  53. msg = fmt.Sprintf("%s with value %q", msg, e.Value)
  54. }
  55. if e.Details != "" {
  56. msg = fmt.Sprintf("%s: %s", msg, e.Details)
  57. }
  58. if e.Err != nil {
  59. msg = fmt.Sprintf("%s: %v", msg, e.Err)
  60. }
  61. return msg
  62. }
  63. // Unwrap returns the underlying error
  64. func (e *Error) Unwrap() error {
  65. return e.Err
  66. }
  67. // Is reports whether target matches this error
  68. func (e *Error) Is(target error) bool {
  69. return errors.Is(e.Err, target)
  70. }
  71. // NewError creates a new config error
  72. func NewError(op string, err error, details string) *Error {
  73. return &Error{
  74. Op: op,
  75. Err: err,
  76. Details: details,
  77. }
  78. }
  79. // NewFieldError creates a new config field error
  80. func NewFieldError(op string, section string, field string, value string, err error, details string) *Error {
  81. return &Error{
  82. Op: op,
  83. Section: section,
  84. Field: field,
  85. Value: value,
  86. Err: err,
  87. Details: details,
  88. }
  89. }
  90. // IsValidationError returns true if the error indicates a validation problem
  91. func IsValidationError(err error) bool {
  92. var e *Error
  93. return errors.As(err, &e) && (errors.Is(e.Err, ErrValidationFailed) ||
  94. errors.Is(e.Err, ErrMissingRequired) ||
  95. errors.Is(e.Err, ErrInvalidValue))
  96. }
  97. // IsFileError returns true if the error is related to file operations
  98. func IsFileError(err error) bool {
  99. var e *Error
  100. return errors.As(err, &e) && (errors.Is(e.Err, ErrFileNotFound) ||
  101. errors.Is(e.Err, ErrFilePermission))
  102. }
  103. // IsParseError returns true if the error is related to parsing
  104. func IsParseError(err error) bool {
  105. var e *Error
  106. return errors.As(err, &e) && errors.Is(e.Err, ErrInvalidYAML)
  107. }