backend/pkg/library/cassandra/errors.go

152 lines
3.8 KiB
Go
Raw Normal View History

2025-11-17 09:31:58 +00:00
package cassandra
import (
"errors"
"fmt"
)
2025-11-18 09:45:38 +00:00
// ErrorCode 定義錯誤代碼
type ErrorCode string
const (
// ErrCodeNotFound 表示記錄未找到
ErrCodeNotFound ErrorCode = "NOT_FOUND"
// ErrCodeConflict 表示衝突(如唯一鍵衝突)
ErrCodeConflict ErrorCode = "CONFLICT"
// ErrCodeInvalidInput 表示輸入參數無效
ErrCodeInvalidInput ErrorCode = "INVALID_INPUT"
// ErrCodeMissingPartition 表示缺少 Partition Key
ErrCodeMissingPartition ErrorCode = "MISSING_PARTITION_KEY"
// ErrCodeNoFieldsToUpdate 表示沒有欄位需要更新
ErrCodeNoFieldsToUpdate ErrorCode = "NO_FIELDS_TO_UPDATE"
// ErrCodeMissingTableName 表示缺少 TableName 方法
ErrCodeMissingTableName ErrorCode = "MISSING_TABLE_NAME"
// ErrCodeMissingWhereCondition 表示缺少 WHERE 條件
ErrCodeMissingWhereCondition ErrorCode = "MISSING_WHERE_CONDITION"
2025-11-19 05:33:06 +00:00
// ErrCodeSAINotSupported 表示不支援 SAI
ErrCodeSAINotSupported ErrorCode = "SAI_NOT_SUPPORTED"
2025-11-17 09:31:58 +00:00
)
// Error 是統一的錯誤類型
type Error struct {
2025-11-18 09:45:38 +00:00
Code ErrorCode
Message string
Table string
Err error
2025-11-17 09:31:58 +00:00
}
// Error 實現 error 介面
func (e *Error) Error() string {
if e.Table != "" {
if e.Err != nil {
2025-11-18 09:45:38 +00:00
return fmt.Sprintf("cassandra[%s] (table: %s): %s: %v", e.Code, e.Table, e.Message, e.Err)
2025-11-17 09:31:58 +00:00
}
2025-11-18 09:45:38 +00:00
return fmt.Sprintf("cassandra[%s] (table: %s): %s", e.Code, e.Table, e.Message)
2025-11-17 09:31:58 +00:00
}
if e.Err != nil {
2025-11-18 09:45:38 +00:00
return fmt.Sprintf("cassandra[%s]: %s: %v", e.Code, e.Message, e.Err)
2025-11-17 09:31:58 +00:00
}
2025-11-18 09:45:38 +00:00
return fmt.Sprintf("cassandra[%s]: %s", e.Code, e.Message)
2025-11-17 09:31:58 +00:00
}
// Unwrap 返回底層錯誤
func (e *Error) Unwrap() error {
return e.Err
}
// WithTable 為錯誤添加表名資訊
func (e *Error) WithTable(table string) *Error {
return &Error{
Code: e.Code,
Message: e.Message,
Table: table,
Err: e.Err,
}
}
// WithError 為錯誤添加底層錯誤
func (e *Error) WithError(err error) *Error {
return &Error{
Code: e.Code,
Message: e.Message,
Table: e.Table,
Err: err,
}
}
// NewError 創建新的錯誤
2025-11-18 09:45:38 +00:00
func NewError(code ErrorCode, message string) *Error {
2025-11-17 09:31:58 +00:00
return &Error{
Code: code,
Message: message,
}
}
2025-11-18 09:45:38 +00:00
// 預定義錯誤
var (
// ErrNotFound 表示記錄未找到
ErrNotFound = &Error{
Code: ErrCodeNotFound,
Message: "record not found",
}
// ErrInvalidInput 表示輸入參數無效
ErrInvalidInput = &Error{
Code: ErrCodeInvalidInput,
Message: "invalid input parameter",
}
// ErrNoPartitionKey 表示缺少 Partition Key
ErrNoPartitionKey = &Error{
Code: ErrCodeMissingPartition,
Message: "no partition key defined in struct",
}
// ErrMissingTableName 表示缺少 TableName 方法
ErrMissingTableName = &Error{
Code: ErrCodeMissingTableName,
Message: "struct must implement TableName() method",
}
// ErrNoFieldsToUpdate 表示沒有欄位需要更新
ErrNoFieldsToUpdate = &Error{
Code: ErrCodeNoFieldsToUpdate,
Message: "no fields to update",
}
// ErrMissingWhereCondition 表示缺少 WHERE 條件
ErrMissingWhereCondition = &Error{
Code: ErrCodeMissingWhereCondition,
Message: "operation requires at least one WHERE condition for safety",
}
// ErrMissingPartitionKey 表示 WHERE 條件中缺少 Partition Key
ErrMissingPartitionKey = &Error{
Code: ErrCodeMissingPartition,
Message: "operation requires all partition keys in WHERE clause",
}
2025-11-19 05:33:06 +00:00
// ErrSAINotSupported 表示不支援 SAI
ErrSAINotSupported = &Error{
Code: ErrCodeSAINotSupported,
Message: "SAI (Storage-Attached Indexing) is not supported in this Cassandra version",
}
2025-11-18 09:45:38 +00:00
)
2025-11-17 09:31:58 +00:00
// IsNotFound 檢查錯誤是否為 NotFound
func IsNotFound(err error) bool {
2025-11-18 09:45:38 +00:00
var e *Error
if errors.As(err, &e) {
return e.Code == ErrCodeNotFound
}
return false
2025-11-17 09:31:58 +00:00
}
2025-11-18 09:45:38 +00:00
// IsConflict 檢查錯誤是否為 Conflict
func IsConflict(err error) bool {
var e *Error
if errors.As(err, &e) {
return e.Code == ErrCodeConflict
}
return false
2025-11-17 09:31:58 +00:00
}