refactor: introduce Wire dependency injection and interface-based architecture
- Add Google Wire for compile-time dependency injection - Replace concrete service types with interfaces across handlers - Remove global state (DB, cache) in favor of constructor injection - Split monolithic files into focused modules: - config: separate files for each config domain - dto: converters split by domain (user, post, message, group) - cache: separate metrics.go and redis_cache.go - Introduce unified apperrors package with string-based error codes - Add transaction support with context-aware repository methods - Upgrade golang.org/x/crypto from 0.17.0 to 0.26.0
This commit is contained in:
121
internal/errors/app_errors.go
Normal file
121
internal/errors/app_errors.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// AppError 统一的应用错误类型
|
||||
type AppError struct {
|
||||
Code string
|
||||
Message string
|
||||
Cause error
|
||||
}
|
||||
|
||||
func (e *AppError) Error() string {
|
||||
if e.Cause != nil {
|
||||
return fmt.Sprintf("[%s] %s: %v", e.Code, e.Message, e.Cause)
|
||||
}
|
||||
return fmt.Sprintf("[%s] %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
func (e *AppError) Unwrap() error {
|
||||
return e.Cause
|
||||
}
|
||||
|
||||
// 预定义错误
|
||||
var (
|
||||
// 通用错误
|
||||
ErrNotFound = &AppError{Code: "NOT_FOUND", Message: "资源不存在"}
|
||||
ErrUnauthorized = &AppError{Code: "UNAUTHORIZED", Message: "未授权"}
|
||||
ErrForbidden = &AppError{Code: "FORBIDDEN", Message: "禁止访问"}
|
||||
ErrBadRequest = &AppError{Code: "BAD_REQUEST", Message: "请求参数错误"}
|
||||
ErrInternal = &AppError{Code: "INTERNAL_ERROR", Message: "内部服务器错误"}
|
||||
|
||||
// 用户相关错误
|
||||
ErrUserNotFound = &AppError{Code: "USER_NOT_FOUND", Message: "用户不存在"}
|
||||
ErrUserAlreadyExists = &AppError{Code: "USER_ALREADY_EXISTS", Message: "用户已存在"}
|
||||
ErrInvalidCredentials = &AppError{Code: "INVALID_CREDENTIALS", Message: "用户名或密码错误"}
|
||||
ErrInvalidUsername = &AppError{Code: "INVALID_USERNAME", Message: "无效的用户名"}
|
||||
ErrInvalidEmail = &AppError{Code: "INVALID_EMAIL", Message: "无效的邮箱"}
|
||||
ErrInvalidPhone = &AppError{Code: "INVALID_PHONE", Message: "无效的手机号"}
|
||||
ErrWeakPassword = &AppError{Code: "WEAK_PASSWORD", Message: "密码强度不足"}
|
||||
ErrUsernameExists = &AppError{Code: "USERNAME_EXISTS", Message: "用户名已存在"}
|
||||
ErrEmailExists = &AppError{Code: "EMAIL_EXISTS", Message: "邮箱已存在"}
|
||||
ErrPhoneExists = &AppError{Code: "PHONE_EXISTS", Message: "手机号已存在"}
|
||||
ErrUserBanned = &AppError{Code: "USER_BANNED", Message: "用户已被封禁"}
|
||||
ErrUserBlocked = &AppError{Code: "USER_BLOCKED", Message: "存在屏蔽关系"}
|
||||
ErrInvalidOperation = &AppError{Code: "INVALID_OPERATION", Message: "无效操作"}
|
||||
ErrEmailServiceUnavailable = &AppError{Code: "EMAIL_SERVICE_UNAVAILABLE", Message: "邮件服务不可用"}
|
||||
ErrVerificationCodeTooFrequent = &AppError{Code: "VERIFICATION_CODE_TOO_FREQUENT", Message: "验证码发送过于频繁"}
|
||||
ErrVerificationCodeInvalid = &AppError{Code: "VERIFICATION_CODE_INVALID", Message: "验证码无效"}
|
||||
ErrVerificationCodeExpired = &AppError{Code: "VERIFICATION_CODE_EXPIRED", Message: "验证码已过期"}
|
||||
ErrVerificationCodeUnavailable = &AppError{Code: "VERIFICATION_CODE_UNAVAILABLE", Message: "验证码存储不可用"}
|
||||
ErrEmailAlreadyVerified = &AppError{Code: "EMAIL_ALREADY_VERIFIED", Message: "邮箱已验证"}
|
||||
ErrEmailNotBound = &AppError{Code: "EMAIL_NOT_BOUND", Message: "邮箱未绑定"}
|
||||
|
||||
// 帖子相关错误
|
||||
ErrPostNotFound = &AppError{Code: "POST_NOT_FOUND", Message: "帖子不存在"}
|
||||
ErrPostDeleted = &AppError{Code: "POST_DELETED", Message: "帖子已删除"}
|
||||
|
||||
// 群组相关错误
|
||||
ErrGroupNotFound = &AppError{Code: "GROUP_NOT_FOUND", Message: "群组不存在"}
|
||||
ErrNotGroupMember = &AppError{Code: "NOT_GROUP_MEMBER", Message: "不是群组成员"}
|
||||
ErrAlreadyGroupMember = &AppError{Code: "ALREADY_GROUP_MEMBER", Message: "已是群组成员"}
|
||||
ErrNotGroupAdmin = &AppError{Code: "NOT_GROUP_ADMIN", Message: "不是群管理员"}
|
||||
ErrNotGroupOwner = &AppError{Code: "NOT_GROUP_OWNER", Message: "不是群主"}
|
||||
ErrGroupFull = &AppError{Code: "GROUP_FULL", Message: "群已满"}
|
||||
ErrCannotRemoveOwner = &AppError{Code: "CANNOT_REMOVE_OWNER", Message: "不能移除群主"}
|
||||
ErrCannotMuteOwner = &AppError{Code: "CANNOT_MUTE_OWNER", Message: "不能禁言群主"}
|
||||
ErrMuted = &AppError{Code: "MUTED", Message: "你已被禁言"}
|
||||
ErrMuteAllEnabled = &AppError{Code: "MUTE_ALL_ENABLED", Message: "全员禁言中"}
|
||||
ErrCannotJoin = &AppError{Code: "CANNOT_JOIN", Message: "该群不允许加入"}
|
||||
ErrJoinRequestPending = &AppError{Code: "JOIN_REQUEST_PENDING", Message: "加群申请已提交"}
|
||||
ErrGroupRequestNotFound = &AppError{Code: "GROUP_REQUEST_NOT_FOUND", Message: "加群请求不存在"}
|
||||
ErrGroupRequestHandled = &AppError{Code: "GROUP_REQUEST_HANDLED", Message: "该加群请求已处理"}
|
||||
ErrNotRequestTarget = &AppError{Code: "NOT_REQUEST_TARGET", Message: "不是邀请目标用户"}
|
||||
ErrNoEligibleInvitee = &AppError{Code: "NO_ELIGIBLE_INVITEE", Message: "没有可邀请的用户"}
|
||||
ErrNotMutualFollow = &AppError{Code: "NOT_MUTUAL_FOLLOW", Message: "仅支持邀请互相关注用户"}
|
||||
ErrInviteNotAccepted = &AppError{Code: "INVITE_NOT_ACCEPTED", Message: "被邀请人尚未同意邀请,无法审批"}
|
||||
|
||||
// 表情包相关错误
|
||||
ErrStickerAlreadyExists = &AppError{Code: "STICKER_ALREADY_EXISTS", Message: "表情包已存在"}
|
||||
ErrInvalidStickerURL = &AppError{Code: "INVALID_STICKER_URL", Message: "无效的表情包URL"}
|
||||
|
||||
// 日程相关错误
|
||||
ErrInvalidSchedulePayload = &AppError{Code: "INVALID_SCHEDULE_PAYLOAD", Message: "无效的日程数据"}
|
||||
ErrScheduleCourseNotFound = &AppError{Code: "SCHEDULE_COURSE_NOT_FOUND", Message: "日程课程不存在"}
|
||||
ErrScheduleForbidden = &AppError{Code: "SCHEDULE_FORBIDDEN", Message: "禁止的日程操作"}
|
||||
ErrScheduleColorDuplicated = &AppError{Code: "SCHEDULE_COLOR_DUPLICATED", Message: "课程颜色已被使用"}
|
||||
|
||||
// 通知相关错误
|
||||
ErrUnauthorizedNotification = &AppError{Code: "UNAUTHORIZED_NOTIFICATION", Message: "无权删除此通知"}
|
||||
)
|
||||
|
||||
// Wrap 包装错误
|
||||
func Wrap(err error, appErr *AppError) *AppError {
|
||||
return &AppError{
|
||||
Code: appErr.Code,
|
||||
Message: appErr.Message,
|
||||
Cause: err,
|
||||
}
|
||||
}
|
||||
|
||||
// New 创建新错误
|
||||
func New(code, message string) *AppError {
|
||||
return &AppError{Code: code, Message: message}
|
||||
}
|
||||
|
||||
// Is 判断是否为特定错误
|
||||
func Is(err, target error) bool {
|
||||
return errors.Is(err, target)
|
||||
}
|
||||
|
||||
// As 将错误转换为 AppError
|
||||
func As(err error) (*AppError, bool) {
|
||||
var appErr *AppError
|
||||
if errors.As(err, &appErr) {
|
||||
return appErr, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
Reference in New Issue
Block a user