168 lines
4.1 KiB
Go
168 lines
4.1 KiB
Go
|
|
package seqlog
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"errors"
|
|||
|
|
"fmt"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 哨兵错误(Sentinel Errors)- 可以使用 errors.Is 进行判断
|
|||
|
|
var (
|
|||
|
|
// ErrNilParameter 表示必需的参数为 nil
|
|||
|
|
ErrNilParameter = errors.New("required parameter is nil")
|
|||
|
|
|
|||
|
|
// ErrInvalidCount 表示 count 参数必须大于 0
|
|||
|
|
ErrInvalidCount = errors.New("count must be greater than 0")
|
|||
|
|
|
|||
|
|
// ErrInvalidRange 表示索引或范围参数无效
|
|||
|
|
ErrInvalidRange = errors.New("invalid index or range")
|
|||
|
|
|
|||
|
|
// ErrAlreadyRunning 表示组件已经在运行
|
|||
|
|
ErrAlreadyRunning = errors.New("already running")
|
|||
|
|
|
|||
|
|
// ErrNotRunning 表示组件未运行
|
|||
|
|
ErrNotRunning = errors.New("not running")
|
|||
|
|
|
|||
|
|
// ErrAlreadyRegistered 表示资源已经注册
|
|||
|
|
ErrAlreadyRegistered = errors.New("already registered")
|
|||
|
|
|
|||
|
|
// ErrNotFound 表示资源未找到
|
|||
|
|
ErrNotFound = errors.New("not found")
|
|||
|
|
|
|||
|
|
// ErrCRCMismatch 表示 CRC 校验失败
|
|||
|
|
ErrCRCMismatch = errors.New("crc mismatch")
|
|||
|
|
|
|||
|
|
// ErrInvalidUUID 表示 UUID 格式无效
|
|||
|
|
ErrInvalidUUID = errors.New("invalid uuid")
|
|||
|
|
|
|||
|
|
// ErrInvalidConfig 表示配置无效
|
|||
|
|
ErrInvalidConfig = errors.New("invalid config")
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// TopicError 表示与 topic 相关的错误
|
|||
|
|
type TopicError struct {
|
|||
|
|
Topic string // topic 名称
|
|||
|
|
Op string // 操作名称(如 "write", "query", "start")
|
|||
|
|
Err error // 底层错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *TopicError) Error() string {
|
|||
|
|
if e.Err != nil {
|
|||
|
|
return fmt.Sprintf("topic %s: %s: %v", e.Topic, e.Op, e.Err)
|
|||
|
|
}
|
|||
|
|
return fmt.Sprintf("topic %s: %s", e.Topic, e.Op)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *TopicError) Unwrap() error {
|
|||
|
|
return e.Err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewTopicError 创建一个 topic 相关的错误
|
|||
|
|
func NewTopicError(topic, op string, err error) *TopicError {
|
|||
|
|
return &TopicError{
|
|||
|
|
Topic: topic,
|
|||
|
|
Op: op,
|
|||
|
|
Err: err,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// FileError 表示文件操作相关的错误
|
|||
|
|
type FileError struct {
|
|||
|
|
Path string // 文件路径
|
|||
|
|
Op string // 操作名称(如 "open", "read", "write")
|
|||
|
|
Err error // 底层错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *FileError) Error() string {
|
|||
|
|
if e.Err != nil {
|
|||
|
|
return fmt.Sprintf("file %s: %s: %v", e.Path, e.Op, e.Err)
|
|||
|
|
}
|
|||
|
|
return fmt.Sprintf("file %s: %s", e.Path, e.Op)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *FileError) Unwrap() error {
|
|||
|
|
return e.Err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewFileError 创建一个文件操作相关的错误
|
|||
|
|
func NewFileError(path, op string, err error) *FileError {
|
|||
|
|
return &FileError{
|
|||
|
|
Path: path,
|
|||
|
|
Op: op,
|
|||
|
|
Err: err,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IndexError 表示索引相关的错误
|
|||
|
|
type IndexError struct {
|
|||
|
|
Index int // 请求的索引
|
|||
|
|
Max int // 最大有效索引
|
|||
|
|
Err error // 底层错误(通常是 ErrInvalidRange)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *IndexError) Error() string {
|
|||
|
|
if e.Err != nil {
|
|||
|
|
return fmt.Sprintf("index %d out of range [0, %d): %v", e.Index, e.Max, e.Err)
|
|||
|
|
}
|
|||
|
|
return fmt.Sprintf("index %d out of range [0, %d)", e.Index, e.Max)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *IndexError) Unwrap() error {
|
|||
|
|
return e.Err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewIndexError 创建一个索引越界错误
|
|||
|
|
func NewIndexError(index, max int) *IndexError {
|
|||
|
|
return &IndexError{
|
|||
|
|
Index: index,
|
|||
|
|
Max: max,
|
|||
|
|
Err: ErrInvalidRange,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ValidationError 表示参数验证错误
|
|||
|
|
type ValidationError struct {
|
|||
|
|
Field string // 字段名称
|
|||
|
|
Message string // 错误消息
|
|||
|
|
Err error // 底层错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *ValidationError) Error() string {
|
|||
|
|
if e.Err != nil {
|
|||
|
|
return fmt.Sprintf("validation error: %s: %s: %v", e.Field, e.Message, e.Err)
|
|||
|
|
}
|
|||
|
|
return fmt.Sprintf("validation error: %s: %s", e.Field, e.Message)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (e *ValidationError) Unwrap() error {
|
|||
|
|
return e.Err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewValidationError 创建一个参数验证错误
|
|||
|
|
func NewValidationError(field, message string, err error) *ValidationError {
|
|||
|
|
return &ValidationError{
|
|||
|
|
Field: field,
|
|||
|
|
Message: message,
|
|||
|
|
Err: err,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IsTopicNotFound 检查错误是否为 topic 不存在
|
|||
|
|
func IsTopicNotFound(err error) bool {
|
|||
|
|
var topicErr *TopicError
|
|||
|
|
if errors.As(err, &topicErr) {
|
|||
|
|
return errors.Is(topicErr.Err, ErrNotFound)
|
|||
|
|
}
|
|||
|
|
return errors.Is(err, ErrNotFound)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IsIndexOutOfRange 检查错误是否为索引越界
|
|||
|
|
func IsIndexOutOfRange(err error) bool {
|
|||
|
|
var indexErr *IndexError
|
|||
|
|
return errors.As(err, &indexErr)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IsCRCMismatch 检查错误是否为 CRC 校验失败
|
|||
|
|
func IsCRCMismatch(err error) bool {
|
|||
|
|
return errors.Is(err, ErrCRCMismatch)
|
|||
|
|
}
|