// Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package db import ( "fmt" "strings" "git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/util" ) // ErrCancelled represents an error due to context cancellation type ErrCancelled struct { Message string } // IsErrCancelled checks if an error is a ErrCancelled. func IsErrCancelled(err error) bool { _, ok := err.(ErrCancelled) return ok } func (err ErrCancelled) Error() string { return "Cancelled: " + err.Message } // ErrCancelledf returns an ErrCancelled for the provided format and args func ErrCancelledf(format string, args ...any) error { return ErrCancelled{ fmt.Sprintf(format, args...), } } // ErrSSHDisabled represents an "SSH disabled" error. type ErrSSHDisabled struct{} // IsErrSSHDisabled checks if an error is a ErrSSHDisabled. func IsErrSSHDisabled(err error) bool { _, ok := err.(ErrSSHDisabled) return ok } func (err ErrSSHDisabled) Error() string { return "SSH is disabled" } // ErrNotExist represents a non-exist error. type ErrNotExist struct { Resource string ID int64 } // IsErrNotExist checks if an error is an ErrNotExist func IsErrNotExist(err error) bool { _, ok := err.(ErrNotExist) return ok } func (err ErrNotExist) Error() string { name := "record" if err.Resource != "" { name = err.Resource } if err.ID != 0 { return fmt.Sprintf("%s does not exist [id: %d]", name, err.ID) } return name + " does not exist" } // Unwrap unwraps this as a ErrNotExist err func (err ErrNotExist) Unwrap() error { return util.ErrNotExist } // IsErrDeadlock checks whether err is a database deadlock. // MySQL returns error 1213 (ER_LOCK_DEADLOCK / SQLSTATE 40001). // PostgreSQL returns SQLSTATE 40P01 with "deadlock detected". // SQLite returns SQLITE_BUSY (error 5) with "database is locked". func IsErrDeadlock(err error) bool { if err == nil { return false } msg := err.Error() // MySQL / MariaDB: "Error 1213 (40001): Deadlock found when trying to get lock" if strings.Contains(msg, "Error 1213") || strings.Contains(msg, "40001") { return true } // PostgreSQL: "deadlock detected" if strings.Contains(msg, "deadlock detected") { return true } // SQLite: "database is locked" if strings.Contains(msg, "database is locked") { return true } return false }