package domain import ( "errors" "fmt" "github.com/zitadel/zitadel/backend/v3/storage/database" "github.com/zitadel/zitadel/internal/zerrors" ) type wrongIDPTypeError struct { expected IDPType got string } func NewIDPWrongTypeError(expected IDPType, got fmt.Stringer) error { return &wrongIDPTypeError{ expected: expected, got: got.String(), } } func (e *wrongIDPTypeError) Error() string { return fmt.Sprintf("wrong idp type returned, expected: %v, got: %v", e.expected, e.got) } func (e *wrongIDPTypeError) Is(target error) bool { _, ok := target.(*wrongIDPTypeError) return ok } type MultipleObjectsUpdatedError struct { Msg string Expected int64 Actual int64 } func NewMultipleObjectsUpdatedError(expected, actual int64) error { return &MultipleObjectsUpdatedError{ Expected: expected, Actual: actual, } } func (err *MultipleObjectsUpdatedError) Error() string { return fmt.Sprintf("Message=expecting %d row(s) updated, got %d", err.Expected, err.Actual) } func (err *MultipleObjectsUpdatedError) Is(target error) bool { _, ok := target.(*MultipleObjectsUpdatedError) return ok } type UnexpectedQueryTypeError[T any] struct { assertedType T } func NewUnexpectedQueryTypeError[T any](assertedType T) error { return &UnexpectedQueryTypeError[T]{ assertedType: assertedType, } } func (u *UnexpectedQueryTypeError[T]) Error() string { return fmt.Sprintf("Message=unexpected query type '%T'", u.assertedType) } type UnexpectedTextQueryOperationError[T any] struct { assertedType T } func NewUnexpectedTextQueryOperationError[T any](assertedType T) error { return &UnexpectedTextQueryOperationError[T]{ assertedType: assertedType, } } func (u *UnexpectedTextQueryOperationError[T]) Error() string { return fmt.Sprintf("Message=unexpected text query operation type '%T'", u.assertedType) } type PasswordVerificationError struct { failedAttempts uint8 } func NewPasswordVerificationError(failedPassAttempts uint8) error { return &PasswordVerificationError{ failedAttempts: failedPassAttempts, } } func (e *PasswordVerificationError) Error() string { return fmt.Sprintf("Message=failed password attempts (%d)", e.failedAttempts) } // handleGetError wraps DB errors coming from Get calls into [zerrors] errors. // // - errorID should be in the format - // - objectType should be the string representation of a DB object (e.g. 'user', 'session', 'idp'...) // // The function wraps [database.NoRowFoundError] to [zerrors.NotFound] error // and any other error to [zerrors.InternalError] func handleGetError(inputErr error, errorID, objectType string) error { if inputErr == nil { return nil } if errors.Is(inputErr, &database.NoRowFoundError{}) { return zerrors.CreateZitadelError(zerrors.KindNotFound, inputErr, errorID, fmt.Sprintf("%s not found", objectType), 1) } return zerrors.CreateZitadelError(zerrors.KindInternal, inputErr, errorID, fmt.Sprintf("failed fetching %s", objectType), 1) } func handleUpdateError(inputErr error, expectedRowCount, actualRowCount int64, errorID, objectType string) error { if inputErr == nil && expectedRowCount == actualRowCount { return nil } if inputErr != nil { return zerrors.CreateZitadelError(zerrors.KindInternal, inputErr, errorID, fmt.Sprintf("failed updating %s", objectType), 1) } if actualRowCount == 0 { return zerrors.CreateZitadelError(zerrors.KindNotFound, nil, errorID, fmt.Sprintf("%s not found", objectType), 1) } if actualRowCount != expectedRowCount { return zerrors.CreateZitadelError(zerrors.KindInternal, NewMultipleObjectsUpdatedError(expectedRowCount, actualRowCount), errorID, "unexpected number of rows updated", 1) } return nil } func (err *PasswordVerificationError) Is(target error) bool { _, ok := target.(*PasswordVerificationError) return ok } type RowsReturnedMismatchError struct { Msg string Expected int64 Actual int64 } func NewRowsReturnedMismatchError(expected, actual int64) error { return &RowsReturnedMismatchError{ Expected: expected, Actual: actual, } } func (err *RowsReturnedMismatchError) Error() string { return fmt.Sprintf("Message=expecting %d row(s) returned, got %d", err.Expected, err.Actual) } func (err *RowsReturnedMismatchError) Is(target error) bool { _, ok := target.(*RowsReturnedMismatchError) return ok }