新增:统一的错误类型系统 (errors.go)
主要功能:
- 定义哨兵错误(Sentinel Errors):ErrNilParameter, ErrInvalidCount,
ErrInvalidRange, ErrAlreadyRunning, ErrNotFound, ErrCRCMismatch 等
- 实现结构化错误类型:TopicError, FileError, IndexError, ValidationError
- 提供错误检查辅助函数:IsTopicNotFound, IsIndexOutOfRange, IsCRCMismatch
- 支持 errors.Is 和 errors.As 进行错误判断
更新相关文件使用新错误类型:
- cursor.go: 使用 ValidationError 和 ErrCRCMismatch
- index.go: 使用 IndexError 处理索引越界
- query.go: 使用 ValidationError 验证参数
- seqlog_manager.go: 使用 TopicError 和 ErrAlreadyRegistered
- topic_processor.go: 使用 ErrAlreadyRunning 和 ErrInvalidConfig
测试覆盖:
- errors_test.go 提供完整的错误类型测试
- 所有现有测试继续通过
使用示例:
```go
// 检查 topic 是否存在
if IsTopicNotFound(err) {
// 处理 topic 不存在的情况
}
// 检查索引越界
if IsIndexOutOfRange(err) {
var indexErr *IndexError
errors.As(err, &indexErr)
fmt.Printf("index %d out of range\n", indexErr.Index)
}
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -86,7 +86,7 @@ func (s *Seqlog) RegisterHandlerWithConfig(topic string, config *TopicConfig) er
|
||||
})
|
||||
} else {
|
||||
// Processor 已存在,handler 不可更新
|
||||
return fmt.Errorf("handler already registered for topic %s", topic)
|
||||
return NewTopicError(topic, "register", ErrAlreadyRegistered)
|
||||
}
|
||||
|
||||
s.logger.Info("handler registered", "topic", topic)
|
||||
@@ -115,7 +115,7 @@ func (s *Seqlog) Start() error {
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.running {
|
||||
return fmt.Errorf("seqlog is already running")
|
||||
return ErrAlreadyRunning
|
||||
}
|
||||
|
||||
s.logger.Info("starting seqlog", "baseDir", s.baseDir, "processors", len(s.processors))
|
||||
@@ -355,7 +355,7 @@ func (s *Seqlog) UpdateTopicConfig(topic string, config *TailConfig) error {
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
return fmt.Errorf("topic %s not found", topic)
|
||||
return NewTopicError(topic, "operation", ErrNotFound)
|
||||
}
|
||||
|
||||
return processor.UpdateTailConfig(config)
|
||||
@@ -368,7 +368,7 @@ func (s *Seqlog) GetTopicConfig(topic string) (*TailConfig, error) {
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("topic %s not found", topic)
|
||||
return nil, NewTopicError(topic, "get", ErrNotFound)
|
||||
}
|
||||
|
||||
return processor.GetTailConfig(), nil
|
||||
@@ -381,7 +381,7 @@ func (s *Seqlog) GetTopicStats(topic string) (Stats, error) {
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
return Stats{}, fmt.Errorf("topic %s not found", topic)
|
||||
return Stats{}, NewTopicError(topic, "get-stats", ErrNotFound)
|
||||
}
|
||||
|
||||
return processor.GetStats(), nil
|
||||
@@ -406,7 +406,7 @@ func (s *Seqlog) NewTopicQuery(topic string) (*RecordQuery, error) {
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("topic %s not found", topic)
|
||||
return nil, NewTopicError(topic, "get", ErrNotFound)
|
||||
}
|
||||
|
||||
return processor.Query(), nil
|
||||
@@ -445,7 +445,7 @@ func (s *Seqlog) GetProcessor(topic string) (*TopicProcessor, error) {
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("topic %s not found", topic)
|
||||
return nil, NewTopicError(topic, "get", ErrNotFound)
|
||||
}
|
||||
|
||||
return processor, nil
|
||||
@@ -532,7 +532,7 @@ func (s *Seqlog) ResetTopic(topic string) error {
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
return fmt.Errorf("topic %s not found", topic)
|
||||
return NewTopicError(topic, "operation", ErrNotFound)
|
||||
}
|
||||
|
||||
// 先停止 processor
|
||||
|
||||
Reference in New Issue
Block a user