129 lines
3.5 KiB
Go
129 lines
3.5 KiB
Go
package errors
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// 錯誤碼定義
|
|
const (
|
|
// 通用錯誤碼 (1000-1999)
|
|
ErrCodeInternal = 1000
|
|
ErrCodeInvalidInput = 1001
|
|
ErrCodeNotFound = 1002
|
|
ErrCodeAlreadyExists = 1003
|
|
ErrCodeUnauthorized = 1004
|
|
ErrCodeForbidden = 1005
|
|
|
|
// 角色相關錯誤碼 (2000-2099)
|
|
ErrCodeRoleNotFound = 2000
|
|
ErrCodeRoleAlreadyExists = 2001
|
|
ErrCodeRoleHasUsers = 2002
|
|
ErrCodeInvalidRoleUID = 2003
|
|
|
|
// 權限相關錯誤碼 (2100-2199)
|
|
ErrCodePermissionNotFound = 2100
|
|
ErrCodePermissionDenied = 2101
|
|
ErrCodeInvalidPermission = 2102
|
|
ErrCodeCircularDependency = 2103
|
|
|
|
// 使用者角色相關錯誤碼 (2200-2299)
|
|
ErrCodeUserRoleNotFound = 2200
|
|
ErrCodeUserRoleAlreadyExists = 2201
|
|
ErrCodeInvalidUserUID = 2202
|
|
|
|
// Repository 相關錯誤碼 (3000-3099)
|
|
ErrCodeDBConnection = 3000
|
|
ErrCodeDBQuery = 3001
|
|
ErrCodeDBTransaction = 3002
|
|
ErrCodeCacheError = 3003
|
|
)
|
|
|
|
// AppError 應用程式錯誤
|
|
type AppError struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
Err error `json:"-"`
|
|
}
|
|
|
|
func (e *AppError) Error() string {
|
|
if e.Err != nil {
|
|
return fmt.Sprintf("[%d] %s: %v", e.Code, e.Message, e.Err)
|
|
}
|
|
return fmt.Sprintf("[%d] %s", e.Code, e.Message)
|
|
}
|
|
|
|
func (e *AppError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
// New 建立新錯誤
|
|
func New(code int, message string) *AppError {
|
|
return &AppError{
|
|
Code: code,
|
|
Message: message,
|
|
}
|
|
}
|
|
|
|
// Wrap 包裝錯誤
|
|
func Wrap(code int, message string, err error) *AppError {
|
|
return &AppError{
|
|
Code: code,
|
|
Message: message,
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
// 預定義錯誤
|
|
var (
|
|
// 通用錯誤
|
|
ErrInternal = New(ErrCodeInternal, "internal server error")
|
|
ErrInvalidInput = New(ErrCodeInvalidInput, "invalid input")
|
|
ErrNotFound = New(ErrCodeNotFound, "resource not found")
|
|
ErrAlreadyExists = New(ErrCodeAlreadyExists, "resource already exists")
|
|
ErrUnauthorized = New(ErrCodeUnauthorized, "unauthorized")
|
|
ErrForbidden = New(ErrCodeForbidden, "forbidden")
|
|
|
|
// 角色錯誤
|
|
ErrRoleNotFound = New(ErrCodeRoleNotFound, "role not found")
|
|
ErrRoleAlreadyExists = New(ErrCodeRoleAlreadyExists, "role already exists")
|
|
ErrRoleHasUsers = New(ErrCodeRoleHasUsers, "role has users")
|
|
ErrInvalidRoleUID = New(ErrCodeInvalidRoleUID, "invalid role uid")
|
|
|
|
// 權限錯誤
|
|
ErrPermissionNotFound = New(ErrCodePermissionNotFound, "permission not found")
|
|
ErrPermissionDenied = New(ErrCodePermissionDenied, "permission denied")
|
|
ErrInvalidPermission = New(ErrCodeInvalidPermission, "invalid permission")
|
|
ErrCircularDependency = New(ErrCodeCircularDependency, "circular dependency detected")
|
|
|
|
// 使用者角色錯誤
|
|
ErrUserRoleNotFound = New(ErrCodeUserRoleNotFound, "user role not found")
|
|
ErrUserRoleAlreadyExists = New(ErrCodeUserRoleAlreadyExists, "user role already exists")
|
|
ErrInvalidUserUID = New(ErrCodeInvalidUserUID, "invalid user uid")
|
|
|
|
// Repository 錯誤
|
|
ErrDBConnection = New(ErrCodeDBConnection, "database connection error")
|
|
ErrDBQuery = New(ErrCodeDBQuery, "database query error")
|
|
ErrDBTransaction = New(ErrCodeDBTransaction, "database transaction error")
|
|
ErrCacheError = New(ErrCodeCacheError, "cache error")
|
|
)
|
|
|
|
// Is 檢查錯誤類型
|
|
func Is(err, target error) bool {
|
|
return errors.Is(err, target)
|
|
}
|
|
|
|
// As 轉換錯誤類型
|
|
func As(err error, target interface{}) bool {
|
|
return errors.As(err, target)
|
|
}
|
|
|
|
// GetCode 取得錯誤碼
|
|
func GetCode(err error) int {
|
|
var appErr *AppError
|
|
if errors.As(err, &appErr) {
|
|
return appErr.Code
|
|
}
|
|
return ErrCodeInternal
|
|
}
|