k8s.io/apiserver@v0.31.1/pkg/cel/errors.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cel
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/google/cel-go/cel"
    23  )
    24  
    25  // ErrInternal the basic error that occurs when the expression fails to evaluate
    26  // due to internal reasons. Any Error that has the Type of
    27  // ErrorInternal is considered equal to ErrInternal
    28  var ErrInternal = fmt.Errorf("internal")
    29  
    30  // ErrInvalid is the basic error that occurs when the expression fails to
    31  // evaluate but not due to internal reasons. Any Error that has the Type of
    32  // ErrorInvalid is considered equal to ErrInvalid.
    33  var ErrInvalid = fmt.Errorf("invalid")
    34  
    35  // ErrRequired is the basic error that occurs when the expression is required
    36  // but absent.
    37  // Any Error that has the Type of ErrorRequired is considered equal
    38  // to ErrRequired.
    39  var ErrRequired = fmt.Errorf("required")
    40  
    41  // ErrCompilation is the basic error that occurs when the expression fails to
    42  // compile. Any CompilationError wraps ErrCompilation.
    43  // ErrCompilation wraps ErrInvalid
    44  var ErrCompilation = fmt.Errorf("%w: compilation error", ErrInvalid)
    45  
    46  // ErrOutOfBudget is the basic error that occurs when the expression fails due to
    47  // exceeding budget.
    48  var ErrOutOfBudget = fmt.Errorf("out of budget")
    49  
    50  // Error is an implementation of the 'error' interface, which represents a
    51  // XValidation error.
    52  type Error struct {
    53  	Type   ErrorType
    54  	Detail string
    55  
    56  	// Cause is an optional wrapped errors that can be useful to
    57  	// programmatically retrieve detailed errors.
    58  	Cause error
    59  }
    60  
    61  var _ error = &Error{}
    62  
    63  // Error implements the error interface.
    64  func (v *Error) Error() string {
    65  	return v.Detail
    66  }
    67  
    68  func (v *Error) Is(err error) bool {
    69  	switch v.Type {
    70  	case ErrorTypeRequired:
    71  		return err == ErrRequired
    72  	case ErrorTypeInvalid:
    73  		return err == ErrInvalid
    74  	case ErrorTypeInternal:
    75  		return err == ErrInternal
    76  	}
    77  	return false
    78  }
    79  
    80  // Unwrap returns the wrapped Cause.
    81  func (v *Error) Unwrap() error {
    82  	return v.Cause
    83  }
    84  
    85  // ErrorType is a machine-readable value providing more detail about why
    86  // a XValidation is invalid.
    87  type ErrorType string
    88  
    89  const (
    90  	// ErrorTypeRequired is used to report withNullable values that are not
    91  	// provided (e.g. empty strings, null values, or empty arrays).  See
    92  	// Required().
    93  	ErrorTypeRequired ErrorType = "RuleRequired"
    94  	// ErrorTypeInvalid is used to report malformed values
    95  	ErrorTypeInvalid ErrorType = "RuleInvalid"
    96  	// ErrorTypeInternal is used to report other errors that are not related
    97  	// to user input.  See InternalError().
    98  	ErrorTypeInternal ErrorType = "InternalError"
    99  )
   100  
   101  // CompilationError indicates an error during expression compilation.
   102  // It wraps ErrCompilation.
   103  type CompilationError struct {
   104  	err    *Error
   105  	Issues *cel.Issues
   106  }
   107  
   108  // NewCompilationError wraps a cel.Issues to indicate a compilation failure.
   109  func NewCompilationError(issues *cel.Issues) *CompilationError {
   110  	return &CompilationError{
   111  		Issues: issues,
   112  		err: &Error{
   113  			Type:   ErrorTypeInvalid,
   114  			Detail: fmt.Sprintf("compilation error: %s", issues),
   115  		}}
   116  }
   117  
   118  func (e *CompilationError) Error() string {
   119  	return e.err.Error()
   120  }
   121  
   122  func (e *CompilationError) Unwrap() []error {
   123  	return []error{e.err, ErrCompilation}
   124  }