Files
ttstd-infinite-canvas/backend/internal/service/errors.go
QAyong 5b7f173102 feat: 完善创作工作台与用户诊断支持 (#295)
* feat(canvas): 参考素材 - 增加移除按钮并删除对应连线

* feat(canvas): 完善节点面板交互与拖拽反馈

* fix(canvas): 画布交互与小地图 - 统一浮层层级并完善节点识别

* feat(prompt-optimizer): 增加 AI 提示词优化器及宿主接入

* feat(canvas): 画布 - 增加自动整理节点按钮并补充文档

* chore(web): 前端 - 修正提示词优化器格式

* chore(backend): 后端 - 修正 Go 格式检查

* feat(workspace): 完善诊断导出与本地排障支持

* chore(web): 格式化诊断导出文件

* fix(web-test): 兼容 Bun 测试运行时

* fix(web-test): 对齐模型目录协议断言
2026-08-25 13:49:15 +08:00

157 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import "fmt"
// AppError 是 service 层对外公开的结构化错误。
// Message 必须可安全展示给用户,Cause 仅用于保留内部诊断链路,不得直接写入 HTTP 响应。
type AppError struct {
Status int
Code int
Message string
Retryable bool
Cause error
}
func (e *AppError) Error() string {
if e == nil {
return ""
}
return e.Message
}
func (e *AppError) Unwrap() error {
if e == nil {
return nil
}
return e.Cause
}
func NewAppError(status int, message string) *AppError {
return &AppError{Status: status, Message: message}
}
func WrapAppError(status int, message string, cause error) *AppError {
return &AppError{Status: status, Message: message, Cause: cause}
}
// ModelErrorCode 定义模型相关的错误码
type ModelErrorCode string
const (
// ErrCodeModelCapabilityNotSupported 当前模型能力不支持请求
ErrCodeModelCapabilityNotSupported ModelErrorCode = "model_capability_not_supported"
// ErrCodeModelPriceNotConfigured 当前模型未配置该能力组合价格
ErrCodeModelPriceNotConfigured ModelErrorCode = "model_price_not_configured"
// ErrCodeModelRouteUnavailable 没有可用供应线路
ErrCodeModelRouteUnavailable ModelErrorCode = "model_route_unavailable"
// ErrCodeProviderRequestFailed 供应商异常、响应格式错误或上游失败
ErrCodeProviderRequestFailed ModelErrorCode = "provider_request_failed"
// ErrCodeModelCatalogMismatch 模型目录已更新,请重新选择
ErrCodeModelCatalogMismatch ModelErrorCode = "model_catalog_mismatch"
// ErrCodeInvalidModelSelection 无效的模型选择
ErrCodeInvalidModelSelection ModelErrorCode = "invalid_model_selection"
)
// ModelError 模型相关的错误,包含错误码和详细信息
// 继承 AppError 以保持兼容性
type ModelError struct {
*AppError
ErrorCode ModelErrorCode
Details map[string]any
}
func (e *ModelError) Error() string {
if e.AppError != nil {
return e.AppError.Error()
}
return string(e.ErrorCode)
}
// NewModelError 创建模型错误
func NewModelError(code ModelErrorCode, message string) *ModelError {
return &ModelError{
AppError: NewAppError(400, message),
ErrorCode: code,
Details: make(map[string]any),
}
}
// WithDetails 添加错误详情
func (e *ModelError) WithDetails(details map[string]any) *ModelError {
e.Details = details
return e
}
// ModelCapabilityNotSupported 当前模型能力不支持请求
func ModelCapabilityNotSupported(message string) error {
if message == "" {
message = "当前模型不支持该能力"
}
return NewModelError(ErrCodeModelCapabilityNotSupported, message)
}
// ModelPriceNotConfigured 当前模型未配置价格
func ModelPriceNotConfigured(message string) error {
if message == "" {
message = "当前模型未配置该能力组合价格"
}
return NewModelError(ErrCodeModelPriceNotConfigured, message)
}
// ModelRouteUnavailable 没有可用供应线路
func ModelRouteUnavailable(message string) error {
if message == "" {
message = "没有可用供应线路"
}
return NewModelError(ErrCodeModelRouteUnavailable, message)
}
// ProviderRequestFailed 供应商请求失败
func ProviderRequestFailed(message string) error {
if message == "" {
message = "模型服务返回失败,请检查请求内容或渠道配置"
}
return NewModelError(ErrCodeProviderRequestFailed, message)
}
// ModelCatalogMismatch 模型目录已更新
func ModelCatalogMismatch(message string) error {
if message == "" {
message = "模型目录已更新,请重新选择"
}
return NewModelError(ErrCodeModelCatalogMismatch, message)
}
// InvalidModelSelection 无效的模型选择
func InvalidModelSelection(message string) error {
if message == "" {
message = "无效的模型选择"
}
return NewModelError(ErrCodeInvalidModelSelection, message)
}
// IsModelError 判断是否为模型错误
func IsModelError(err error) bool {
_, ok := err.(*ModelError)
return ok
}
// GetModelErrorCode 获取模型错误码
func GetModelErrorCode(err error) ModelErrorCode {
if modelErr, ok := err.(*ModelError); ok {
return modelErr.ErrorCode
}
return ""
}
// FormatModelError 格式化模型错误消息
func FormatModelError(err error) string {
if modelErr, ok := err.(*ModelError); ok {
if len(modelErr.Details) > 0 {
return fmt.Sprintf("%s (错误码: %s)", modelErr.Message, modelErr.ErrorCode)
}
return modelErr.Message
}
return err.Error()
}