Skip to content

Errors

All error types, sentinel values, and helper functions in the github.com/pthm/melange/melange package.

Sentinel Errors

ErrorMeaningCommon Cause
ErrNoTuplesTablemelange_tuples view or table not foundView not created, wrong search path
ErrInvalidSchemaSchema parsing failedSyntax error in .fga file
ErrMissingFunctionRequired PostgreSQL function missingMigration not run, or Melange updated without re-migrating
ErrCyclicSchemaCycle detected in relation graphCircular implied-by chain
ErrBulkCheckDeniedAt least one bulk check was deniedReturned by BulkCheckResults.AllOrError()
ErrContextualTuplesUnsupportedQuerier does not support contextual tuplesUsing *sql.DB instead of *sql.Tx or *sql.Conn
ErrInvalidContextualTupleContextual tuple failed validationMalformed or schema-invalid tuple

All sentinel errors work with errors.Is:

allowed, err := checker.Check(ctx, subject, relation, object)
if melange.IsNoTuplesTableErr(err) {
    // melange_tuples view is missing
}

Error Helper Functions

FunctionChecks for
IsNoTuplesTableErr(err error) boolErrNoTuplesTable
IsInvalidSchemaErr(err error) boolErrInvalidSchema
IsMissingFunctionErr(err error) boolErrMissingFunction
IsCyclicSchemaErr(err error) boolErrCyclicSchema
IsBulkCheckDeniedErr(err error) boolErrBulkCheckDenied
IsValidationError(err error) boolValidationError
GetValidationErrorCode(err error) intReturns code from ValidationError, or 0

ValidationError

type ValidationError struct {
    Code    int
    Message string
}

Methods:

  • Error() string implements the error interface
  • ErrorCode() int returns the OpenFGA-compatible error code

Error Codes

CodeConstantMeaning
2000ErrorCodeValidationInvalid request (bad input)
2001ErrorCodeAuthorizationModelNotFoundAuthorization model not found
2002ErrorCodeResolutionTooComplexResolution depth or complexity limit exceeded
allowed, err := checker.Check(ctx, subject, relation, object)
if melange.IsValidationError(err) {
    code := melange.GetValidationErrorCode(err)
    switch code {
    case melange.ErrorCodeValidation:
        // bad input
    case melange.ErrorCodeResolutionTooComplex:
        // depth limit hit
    }
}

BulkCheckDeniedError

type BulkCheckDeniedError struct {
    Subject  Object
    Relation Relation
    Object   Object
    Index    int   // Position in original request order
    Total    int   // Total denied checks in batch
}

Methods:

  • Error() string implements the error interface
  • Unwrap() error returns ErrBulkCheckDenied

Returned by BulkCheckResults.AllOrError() when at least one check is denied:

err := results.AllOrError()
if err != nil {
    var denied *melange.BulkCheckDeniedError
    if errors.As(err, &denied) {
        log.Printf("denied: %s %s %s (and %d others)",
            denied.Subject, denied.Relation, denied.Object, denied.Total-1)
    }
}

PostgreSQL Error Mapping

The runtime maps PostgreSQL error codes to sentinel errors:

SQLSTATEPostgreSQL ErrorMapped To
42P01Undefined tableErrNoTuplesTable
42883Undefined functionErrMissingFunction
M2002Custom (raised by generated functions)ValidationError with code 2002

Next Steps