github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/typesystem/errors.go (about)

     1  package typesystem
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/rs/zerolog"
     9  
    10  	"github.com/authzed/spicedb/internal/sharederrors"
    11  )
    12  
    13  // ErrNamespaceNotFound occurs when a namespace was not found.
    14  type ErrNamespaceNotFound struct {
    15  	error
    16  	namespaceName string
    17  }
    18  
    19  // NotFoundNamespaceName is the name of the namespace not found.
    20  func (err ErrNamespaceNotFound) NotFoundNamespaceName() string {
    21  	return err.namespaceName
    22  }
    23  
    24  // MarshalZerologObject implements zerolog object marshalling.
    25  func (err ErrNamespaceNotFound) MarshalZerologObject(e *zerolog.Event) {
    26  	e.Err(err.error).Str("namespace", err.namespaceName)
    27  }
    28  
    29  // DetailsMetadata returns the metadata for details for this error.
    30  func (err ErrNamespaceNotFound) DetailsMetadata() map[string]string {
    31  	return map[string]string{
    32  		"definition_name": err.namespaceName,
    33  	}
    34  }
    35  
    36  // ErrRelationNotFound occurs when a relation was not found under a namespace.
    37  type ErrRelationNotFound struct {
    38  	error
    39  	namespaceName string
    40  	relationName  string
    41  }
    42  
    43  // NamespaceName returns the name of the namespace in which the relation was not found.
    44  func (err ErrRelationNotFound) NamespaceName() string {
    45  	return err.namespaceName
    46  }
    47  
    48  // NotFoundRelationName returns the name of the relation not found.
    49  func (err ErrRelationNotFound) NotFoundRelationName() string {
    50  	return err.relationName
    51  }
    52  
    53  func (err ErrRelationNotFound) MarshalZerologObject(e *zerolog.Event) {
    54  	e.Err(err.error).Str("namespace", err.namespaceName).Str("relation", err.relationName)
    55  }
    56  
    57  // DetailsMetadata returns the metadata for details for this error.
    58  func (err ErrRelationNotFound) DetailsMetadata() map[string]string {
    59  	return map[string]string{
    60  		"definition_name":             err.namespaceName,
    61  		"relation_or_permission_name": err.relationName,
    62  	}
    63  }
    64  
    65  // ErrCaveatNotFound occurs when a caveat was not found.
    66  type ErrCaveatNotFound struct {
    67  	error
    68  	caveatName string
    69  }
    70  
    71  // CaveatName returns the name of the caveat not found.
    72  func (err ErrCaveatNotFound) CaveatName() string {
    73  	return err.caveatName
    74  }
    75  
    76  func (err ErrCaveatNotFound) MarshalZerologObject(e *zerolog.Event) {
    77  	e.Err(err.error).Str("caveat", err.caveatName)
    78  }
    79  
    80  // DetailsMetadata returns the metadata for details for this error.
    81  func (err ErrCaveatNotFound) DetailsMetadata() map[string]string {
    82  	return map[string]string{
    83  		"caveat_name": err.caveatName,
    84  	}
    85  }
    86  
    87  // ErrDuplicateRelation occurs when a duplicate relation was found inside a namespace.
    88  type ErrDuplicateRelation struct {
    89  	error
    90  	namespaceName string
    91  	relationName  string
    92  }
    93  
    94  // MarshalZerologObject implements zerolog object marshalling.
    95  func (err ErrDuplicateRelation) MarshalZerologObject(e *zerolog.Event) {
    96  	e.Err(err.error).Str("namespace", err.namespaceName).Str("relation", err.relationName)
    97  }
    98  
    99  // DetailsMetadata returns the metadata for details for this error.
   100  func (err ErrDuplicateRelation) DetailsMetadata() map[string]string {
   101  	return map[string]string{
   102  		"definition_name":             err.namespaceName,
   103  		"relation_or_permission_name": err.relationName,
   104  	}
   105  }
   106  
   107  // ErrPermissionUsedOnLeftOfArrow occurs when a permission is used on the left side of an arrow
   108  // expression.
   109  type ErrPermissionUsedOnLeftOfArrow struct {
   110  	error
   111  	namespaceName        string
   112  	parentPermissionName string
   113  	foundPermissionName  string
   114  }
   115  
   116  // MarshalZerologObject implements zerolog object marshalling.
   117  func (err ErrPermissionUsedOnLeftOfArrow) MarshalZerologObject(e *zerolog.Event) {
   118  	e.Err(err.error).Str("namespace", err.namespaceName).Str("permission", err.parentPermissionName).Str("usedPermission", err.foundPermissionName)
   119  }
   120  
   121  // DetailsMetadata returns the metadata for details for this error.
   122  func (err ErrPermissionUsedOnLeftOfArrow) DetailsMetadata() map[string]string {
   123  	return map[string]string{
   124  		"definition_name":      err.namespaceName,
   125  		"permission_name":      err.parentPermissionName,
   126  		"used_permission_name": err.foundPermissionName,
   127  	}
   128  }
   129  
   130  // ErrWildcardUsedInArrow occurs when an arrow operates over a relation that contains a wildcard.
   131  type ErrWildcardUsedInArrow struct {
   132  	error
   133  	namespaceName        string
   134  	parentPermissionName string
   135  	accessedRelationName string
   136  }
   137  
   138  // MarshalZerologObject implements zerolog object marshalling.
   139  func (err ErrWildcardUsedInArrow) MarshalZerologObject(e *zerolog.Event) {
   140  	e.Err(err.error).Str("namespace", err.namespaceName).Str("parentPermissionName", err.parentPermissionName).Str("accessedRelationName", err.accessedRelationName)
   141  }
   142  
   143  // DetailsMetadata returns the metadata for details for this error.
   144  func (err ErrWildcardUsedInArrow) DetailsMetadata() map[string]string {
   145  	return map[string]string{
   146  		"definition_name":        err.namespaceName,
   147  		"permission_name":        err.parentPermissionName,
   148  		"accessed_relation_name": err.accessedRelationName,
   149  	}
   150  }
   151  
   152  // ErrMissingAllowedRelations occurs when a relation is defined without any type information.
   153  type ErrMissingAllowedRelations struct {
   154  	error
   155  	namespaceName string
   156  	relationName  string
   157  }
   158  
   159  // MarshalZerologObject implements zerolog object marshalling.
   160  func (err ErrMissingAllowedRelations) MarshalZerologObject(e *zerolog.Event) {
   161  	e.Err(err.error).Str("namespace", err.namespaceName).Str("relation", err.relationName)
   162  }
   163  
   164  // DetailsMetadata returns the metadata for details for this error.
   165  func (err ErrMissingAllowedRelations) DetailsMetadata() map[string]string {
   166  	return map[string]string{
   167  		"definition_name": err.namespaceName,
   168  		"relation_name":   err.relationName,
   169  	}
   170  }
   171  
   172  // ErrTransitiveWildcard occurs when a wildcard relation in turn references another wildcard
   173  // relation.
   174  type ErrTransitiveWildcard struct {
   175  	error
   176  	namespaceName string
   177  	relationName  string
   178  }
   179  
   180  // MarshalZerologObject implements zerolog object marshalling.
   181  func (err ErrTransitiveWildcard) MarshalZerologObject(e *zerolog.Event) {
   182  	e.Err(err.error).Str("namespace", err.namespaceName).Str("relation", err.relationName)
   183  }
   184  
   185  // DetailsMetadata returns the metadata for details for this error.
   186  func (err ErrTransitiveWildcard) DetailsMetadata() map[string]string {
   187  	return map[string]string{
   188  		"definition_name": err.namespaceName,
   189  		"relation_name":   err.relationName,
   190  	}
   191  }
   192  
   193  // ErrPermissionsCycle occurs when a cycle exists within permissions.
   194  type ErrPermissionsCycle struct {
   195  	error
   196  	namespaceName   string
   197  	permissionNames []string
   198  }
   199  
   200  // MarshalZerologObject implements zerolog object marshalling.
   201  func (err ErrPermissionsCycle) MarshalZerologObject(e *zerolog.Event) {
   202  	e.Err(err.error).Str("namespace", err.namespaceName).Str("permissions", strings.Join(err.permissionNames, ", "))
   203  }
   204  
   205  // DetailsMetadata returns the metadata for details for this error.
   206  func (err ErrPermissionsCycle) DetailsMetadata() map[string]string {
   207  	return map[string]string{
   208  		"definition_name":  err.namespaceName,
   209  		"permission_names": strings.Join(err.permissionNames, ","),
   210  	}
   211  }
   212  
   213  // ErrDuplicateAllowedRelation indicates that an allowed relation was redefined on a relation.
   214  type ErrDuplicateAllowedRelation struct {
   215  	error
   216  	namespaceName         string
   217  	relationName          string
   218  	allowedRelationSource string
   219  }
   220  
   221  // MarshalZerologObject implements zerolog object marshalling.
   222  func (err ErrDuplicateAllowedRelation) MarshalZerologObject(e *zerolog.Event) {
   223  	e.Err(err.error).Str("namespace", err.namespaceName).Str("relation", err.relationName).Str("allowed-relation", err.allowedRelationSource)
   224  }
   225  
   226  // DetailsMetadata returns the metadata for details for this error.
   227  func (err ErrDuplicateAllowedRelation) DetailsMetadata() map[string]string {
   228  	return map[string]string{
   229  		"definition_name":  err.namespaceName,
   230  		"relation_name":    err.relationName,
   231  		"allowed_relation": err.allowedRelationSource,
   232  	}
   233  }
   234  
   235  // ErrUnusedCaveatParameter indicates that a caveat parameter is unused in the caveat expression.
   236  type ErrUnusedCaveatParameter struct {
   237  	error
   238  	caveatName string
   239  	paramName  string
   240  }
   241  
   242  // MarshalZerologObject implements zerolog object marshalling.
   243  func (err ErrUnusedCaveatParameter) MarshalZerologObject(e *zerolog.Event) {
   244  	e.Err(err.error).Str("caveat", err.caveatName).Str("param", err.paramName)
   245  }
   246  
   247  // DetailsMetadata returns the metadata for details for this error.
   248  func (err ErrUnusedCaveatParameter) DetailsMetadata() map[string]string {
   249  	return map[string]string{
   250  		"caveat_name":    err.caveatName,
   251  		"parameter_name": err.paramName,
   252  	}
   253  }
   254  
   255  // NewNamespaceNotFoundErr constructs a new namespace not found error.
   256  func NewNamespaceNotFoundErr(nsName string) error {
   257  	return ErrNamespaceNotFound{
   258  		error:         fmt.Errorf("object definition `%s` not found", nsName),
   259  		namespaceName: nsName,
   260  	}
   261  }
   262  
   263  // NewRelationNotFoundErr constructs a new relation not found error.
   264  func NewRelationNotFoundErr(nsName string, relationName string) error {
   265  	return ErrRelationNotFound{
   266  		error:         fmt.Errorf("relation/permission `%s` not found under definition `%s`", relationName, nsName),
   267  		namespaceName: nsName,
   268  		relationName:  relationName,
   269  	}
   270  }
   271  
   272  // NewCaveatNotFoundErr constructs a new caveat not found error.
   273  func NewCaveatNotFoundErr(caveatName string) error {
   274  	return ErrCaveatNotFound{
   275  		error:      fmt.Errorf("caveat `%s` not found", caveatName),
   276  		caveatName: caveatName,
   277  	}
   278  }
   279  
   280  // NewDuplicateRelationError constructs an error indicating that a relation was defined more than once in a namespace.
   281  func NewDuplicateRelationError(nsName string, relationName string) error {
   282  	return ErrDuplicateRelation{
   283  		error:         fmt.Errorf("found duplicate relation/permission name `%s` under definition `%s`", relationName, nsName),
   284  		namespaceName: nsName,
   285  		relationName:  relationName,
   286  	}
   287  }
   288  
   289  // NewDuplicateAllowedRelationErr constructs an error indicating that an allowed relation was defined more than once for a relation.
   290  func NewDuplicateAllowedRelationErr(nsName string, relationName string, allowedRelationSource string) error {
   291  	return ErrDuplicateAllowedRelation{
   292  		error:                 fmt.Errorf("found duplicate allowed subject type `%s` on relation `%s` under definition `%s`", allowedRelationSource, relationName, nsName),
   293  		namespaceName:         nsName,
   294  		relationName:          relationName,
   295  		allowedRelationSource: allowedRelationSource,
   296  	}
   297  }
   298  
   299  // NewPermissionUsedOnLeftOfArrowErr constructs an error indicating that a permission was used on the left side of an arrow.
   300  func NewPermissionUsedOnLeftOfArrowErr(nsName string, parentPermissionName string, foundPermissionName string) error {
   301  	return ErrPermissionUsedOnLeftOfArrow{
   302  		error:                fmt.Errorf("under permission `%s` under definition `%s`: permissions cannot be used on the left hand side of an arrow (found `%s`)", parentPermissionName, nsName, foundPermissionName),
   303  		namespaceName:        nsName,
   304  		parentPermissionName: parentPermissionName,
   305  		foundPermissionName:  foundPermissionName,
   306  	}
   307  }
   308  
   309  // NewWildcardUsedInArrowErr constructs an error indicating that an arrow operated over a relation with a wildcard type.
   310  func NewWildcardUsedInArrowErr(nsName string, parentPermissionName string, foundRelationName string, wildcardTypeName string, wildcardRelationName string) error {
   311  	return ErrWildcardUsedInArrow{
   312  		error:                fmt.Errorf("for arrow under permission `%s`: relation `%s#%s` includes wildcard type `%s` via relation `%s`: wildcard relations cannot be used on the left side of arrows", parentPermissionName, nsName, foundRelationName, wildcardTypeName, wildcardRelationName),
   313  		namespaceName:        nsName,
   314  		parentPermissionName: parentPermissionName,
   315  		accessedRelationName: foundRelationName,
   316  	}
   317  }
   318  
   319  // NewMissingAllowedRelationsErr constructs an error indicating that type information is missing for a relation.
   320  func NewMissingAllowedRelationsErr(nsName string, relationName string) error {
   321  	return ErrMissingAllowedRelations{
   322  		error:         fmt.Errorf("at least one allowed relation/permission is required to be defined for relation `%s`", relationName),
   323  		namespaceName: nsName,
   324  		relationName:  relationName,
   325  	}
   326  }
   327  
   328  // NewTransitiveWildcardErr constructs an error indicating that a transitive wildcard exists.
   329  func NewTransitiveWildcardErr(nsName string, relationName string, foundRelationNamespace string, foundRelationName string, wildcardTypeName string, wildcardRelationReference string) error {
   330  	return ErrTransitiveWildcard{
   331  		error:         fmt.Errorf("for relation `%s`: relation/permission `%s#%s` includes wildcard type `%s` via relation `%s`: wildcard relations cannot be transitively included", relationName, foundRelationNamespace, foundRelationName, wildcardTypeName, wildcardRelationReference),
   332  		namespaceName: nsName,
   333  		relationName:  relationName,
   334  	}
   335  }
   336  
   337  // NewPermissionsCycleErr constructs an error indicating that a cycle exists amongst permissions.
   338  func NewPermissionsCycleErr(nsName string, permissionNames []string) error {
   339  	return ErrPermissionsCycle{
   340  		error:           fmt.Errorf("under definition `%s`, there exists a cycle in permissions: %s", nsName, strings.Join(permissionNames, ", ")),
   341  		namespaceName:   nsName,
   342  		permissionNames: permissionNames,
   343  	}
   344  }
   345  
   346  // NewUnusedCaveatParameterErr constructs indicating that a parameter was unused in a caveat expression.
   347  func NewUnusedCaveatParameterErr(caveatName string, paramName string) error {
   348  	return ErrUnusedCaveatParameter{
   349  		error:      fmt.Errorf("parameter `%s` for caveat `%s` is unused", paramName, caveatName),
   350  		caveatName: caveatName,
   351  		paramName:  paramName,
   352  	}
   353  }
   354  
   355  // asTypeError wraps another error in a type error.
   356  func asTypeError(wrapped error) error {
   357  	if wrapped == nil {
   358  		return nil
   359  	}
   360  
   361  	var te TypeError
   362  	if errors.As(wrapped, &te) {
   363  		return wrapped
   364  	}
   365  
   366  	return TypeError{wrapped}
   367  }
   368  
   369  // TypeError wraps another error as a type error.
   370  type TypeError struct {
   371  	error
   372  }
   373  
   374  func (err TypeError) Unwrap() error {
   375  	return err.error
   376  }
   377  
   378  var (
   379  	_ sharederrors.UnknownNamespaceError = ErrNamespaceNotFound{}
   380  	_ sharederrors.UnknownRelationError  = ErrRelationNotFound{}
   381  )