package errcode import "fmt" // Severity 是错误对调用方的严重级别,供日志与告警使用。 type Severity string const ( SeverityInfo Severity = "info" SeverityWarn Severity = "warn" SeverityError Severity = "error" SeverityFatal Severity = "fatal" ) // Valid 报告严重级别是否为已登记取值。 func (s Severity) Valid() bool { switch s { case SeverityInfo, SeverityWarn, SeverityError, SeverityFatal: return true default: return false } } // Retry 是该错误码的默认重试策略。实例级是否重试仍可由调用方覆盖。 type Retry string const ( // RetryNever 禁止当成功路径重放。 RetryNever Retry = "never" // RetryTransient 允许有界重试(传输抖动、限流、短暂不可用)。 RetryTransient Retry = "transient" // RetryAlways 允许重试;仍须结合 SideEffects,possible 时不得无条件重放。 RetryAlways Retry = "always" ) // Valid 报告重试策略是否为已登记取值。 func (r Retry) Valid() bool { switch r { case RetryNever, RetryTransient, RetryAlways: return true default: return false } } // SideEffects 描述失败时是否可能已产生外部副作用。 // 语义对齐 agent-native contract:possible/unknown 禁止无条件重放。 type SideEffects string const ( SideEffectNone SideEffects = "none" SideEffectPossible SideEffects = "possible" SideEffectUnknown SideEffects = "unknown" ) // Valid 报告副作用分类是否为已登记取值。 func (s SideEffects) Valid() bool { switch s { case SideEffectNone, SideEffectPossible, SideEffectUnknown: return true default: return false } } // Definition 是一条错误码的稳定元数据。Go 登记是权威来源,JSON 是导出形式。 type Definition struct { Code Code `json:"code"` HTTP int `json:"http"` Severity Severity `json:"severity"` Retry Retry `json:"retry"` SideEffects SideEffects `json:"side_effects"` Summary string `json:"summary"` Hint string `json:"hint"` Aliases []string `json:"aliases,omitempty"` } // Validate 检查定义是否可登记。 func (d Definition) Validate() error { if !d.Code.Valid() { return fmt.Errorf("errcode: invalid code %q", d.Code) } if d.HTTP < 100 || d.HTTP > 599 { return fmt.Errorf("errcode: %s: http status %d out of range", d.Code, d.HTTP) } if !d.Severity.Valid() { return fmt.Errorf("errcode: %s: invalid severity %q", d.Code, d.Severity) } if !d.Retry.Valid() { return fmt.Errorf("errcode: %s: invalid retry %q", d.Code, d.Retry) } if !d.SideEffects.Valid() { return fmt.Errorf("errcode: %s: invalid side_effects %q", d.Code, d.SideEffects) } if d.Summary == "" { return fmt.Errorf("errcode: %s: summary is required", d.Code) } if d.Hint == "" { return fmt.Errorf("errcode: %s: hint is required", d.Code) } return nil }