diff --git a/model/histogram/generic.go b/model/histogram/generic.go index 93ac768449..cd385407d5 100644 --- a/model/histogram/generic.go +++ b/model/histogram/generic.go @@ -28,33 +28,41 @@ const ( CustomBucketsSchema int32 = -53 ) +type Error struct { + error +} + +func (e Error) Unwrap() error { + return e.error +} + var ( - ErrHistogramCountNotBigEnough = errors.New("histogram's observation count should be at least the number of observations found in the buckets") - ErrHistogramCountMismatch = errors.New("histogram's observation count should equal the number of observations found in the buckets (in absence of NaN)") - ErrHistogramNegativeCount = errors.New("histogram's observation count is negative") - ErrHistogramNegativeBucketCount = errors.New("histogram has a bucket whose observation count is negative") - ErrHistogramSpanNegativeOffset = errors.New("histogram has a span whose offset is negative") - ErrHistogramSpansBucketsMismatch = errors.New("histogram spans specify different number of buckets than provided") - ErrHistogramCustomBucketsMismatch = errors.New("histogram custom bounds are too few") - ErrHistogramCustomBucketsInvalid = errors.New("histogram custom bounds must be in strictly increasing order") - ErrHistogramCustomBucketsInfinite = errors.New("histogram custom bounds must be finite") - ErrHistogramCustomBucketsNaN = errors.New("histogram custom bounds must not be NaN") - ErrHistogramsIncompatibleSchema = errors.New("cannot apply this operation on histograms with a mix of exponential and custom bucket schemas") - ErrHistogramCustomBucketsZeroCount = errors.New("custom buckets: must have zero count of 0") - ErrHistogramCustomBucketsZeroThresh = errors.New("custom buckets: must have zero threshold of 0") - ErrHistogramCustomBucketsNegSpans = errors.New("custom buckets: must not have negative spans") - ErrHistogramCustomBucketsNegBuckets = errors.New("custom buckets: must not have negative buckets") - ErrHistogramExpSchemaCustomBounds = errors.New("histogram with exponential schema must not have custom bounds") - ErrHistogramsInvalidSchema = fmt.Errorf("histogram has an invalid schema, which must be between %d and %d for exponential buckets, or %d for custom buckets", ExponentialSchemaMin, ExponentialSchemaMax, CustomBucketsSchema) - ErrHistogramsUnknownSchema = fmt.Errorf("histogram has an unknown schema, which must be between %d and %d for exponential buckets, or %d for custom buckets", ExponentialSchemaMinReserved, ExponentialSchemaMaxReserved, CustomBucketsSchema) + ErrHistogramCountNotBigEnough = Error{error: errors.New("histogram's observation count should be at least the number of observations found in the buckets")} + ErrHistogramCountMismatch = Error{error: errors.New("histogram's observation count should equal the number of observations found in the buckets (in absence of NaN)")} + ErrHistogramNegativeCount = Error{error: errors.New("histogram's observation count is negative")} + ErrHistogramNegativeBucketCount = Error{error: errors.New("histogram has a bucket whose observation count is negative")} + ErrHistogramSpanNegativeOffset = Error{error: errors.New("histogram has a span whose offset is negative")} + ErrHistogramSpansBucketsMismatch = Error{error: errors.New("histogram spans specify different number of buckets than provided")} + ErrHistogramCustomBucketsMismatch = Error{error: errors.New("histogram custom bounds are too few")} + ErrHistogramCustomBucketsInvalid = Error{error: errors.New("histogram custom bounds must be in strictly increasing order")} + ErrHistogramCustomBucketsInfinite = Error{error: errors.New("histogram custom bounds must be finite")} + ErrHistogramCustomBucketsNaN = Error{error: errors.New("histogram custom bounds must not be NaN")} + ErrHistogramsIncompatibleSchema = Error{error: errors.New("cannot apply this operation on histograms with a mix of exponential and custom bucket schemas")} + ErrHistogramCustomBucketsZeroCount = Error{error: errors.New("custom buckets: must have zero count of 0")} + ErrHistogramCustomBucketsZeroThresh = Error{error: errors.New("custom buckets: must have zero threshold of 0")} + ErrHistogramCustomBucketsNegSpans = Error{error: errors.New("custom buckets: must not have negative spans")} + ErrHistogramCustomBucketsNegBuckets = Error{error: errors.New("custom buckets: must not have negative buckets")} + ErrHistogramExpSchemaCustomBounds = Error{error: errors.New("histogram with exponential schema must not have custom bounds")} + ErrHistogramsInvalidSchema = Error{error: fmt.Errorf("histogram has an invalid schema, which must be between %d and %d for exponential buckets, or %d for custom buckets", ExponentialSchemaMin, ExponentialSchemaMax, CustomBucketsSchema)} + ErrHistogramsUnknownSchema = Error{error: fmt.Errorf("histogram has an unknown schema, which must be between %d and %d for exponential buckets, or %d for custom buckets", ExponentialSchemaMinReserved, ExponentialSchemaMaxReserved, CustomBucketsSchema)} ) func InvalidSchemaError(s int32) error { - return fmt.Errorf("%w, got schema %d", ErrHistogramsInvalidSchema, s) + return Error{error: fmt.Errorf("%w, got schema %d", ErrHistogramsInvalidSchema, s)} } func UnknownSchemaError(s int32) error { - return fmt.Errorf("%w, got schema %d", ErrHistogramsUnknownSchema, s) + return Error{error: fmt.Errorf("%w, got schema %d", ErrHistogramsUnknownSchema, s)} } func IsCustomBucketsSchema(s int32) bool { diff --git a/storage/remote/write_handler.go b/storage/remote/write_handler.go index 66eaf88189..c19b499e1f 100644 --- a/storage/remote/write_handler.go +++ b/storage/remote/write_handler.go @@ -89,22 +89,8 @@ func NewWriteHandler(logger *slog.Logger, reg prometheus.Registerer, appendable // isHistogramValidationError checks if the error is a native histogram validation error. func isHistogramValidationError(err error) bool { - // TODO: Consider adding single histogram error type instead of individual sentinel errors. - return errors.Is(err, histogram.ErrHistogramCountMismatch) || - errors.Is(err, histogram.ErrHistogramCountNotBigEnough) || - errors.Is(err, histogram.ErrHistogramNegativeCount) || - errors.Is(err, histogram.ErrHistogramNegativeBucketCount) || - errors.Is(err, histogram.ErrHistogramSpanNegativeOffset) || - errors.Is(err, histogram.ErrHistogramSpansBucketsMismatch) || - errors.Is(err, histogram.ErrHistogramCustomBucketsMismatch) || - errors.Is(err, histogram.ErrHistogramCustomBucketsInvalid) || - errors.Is(err, histogram.ErrHistogramCustomBucketsInfinite) || - errors.Is(err, histogram.ErrHistogramCustomBucketsNaN) || - errors.Is(err, histogram.ErrHistogramCustomBucketsZeroCount) || - errors.Is(err, histogram.ErrHistogramCustomBucketsZeroThresh) || - errors.Is(err, histogram.ErrHistogramCustomBucketsNegSpans) || - errors.Is(err, histogram.ErrHistogramCustomBucketsNegBuckets) || - errors.Is(err, histogram.ErrHistogramExpSchemaCustomBounds) + var e histogram.Error + return errors.As(err, &e) } // Store implements remoteapi.writeStorage interface.