chore: stabilize lint and verify builds

This commit is contained in:
2026-02-06 11:51:32 +08:00
parent edede17880
commit 1782f64417
114 changed files with 3032 additions and 1345 deletions

View File

@@ -8,7 +8,7 @@ import (
"github.com/gofiber/fiber/v3/binder"
"github.com/gofiber/utils/v2"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
logrus "github.com/sirupsen/logrus"
"gorm.io/gorm"
"quyun/v2/database/models"
@@ -28,18 +28,22 @@ func NewResponseSender() *ResponseSender {
}
// SendError 发送错误响应
func (s *ResponseSender) SendError(ctx fiber.Ctx, err error) error {
appErr := s.handler.Handle(err)
func (sender *ResponseSender) SendError(ctx fiber.Ctx, err error) error {
appErr := sender.handler.Handle(err)
if appErr == nil {
return nil
}
// 记录错误日志
s.logError(appErr, ctx)
sender.logError(appErr, ctx)
// 根据 Content-Type 返回不同格式
return s.sendResponse(ctx, appErr)
return sender.sendResponse(ctx, appErr)
}
// logError 记录错误日志
func (s *ResponseSender) logError(appErr *AppError, ctx fiber.Ctx) {
func (sender *ResponseSender) logError(appErr *AppError, ctx fiber.Ctx) {
// 确保每个错误实例都有唯一ID便于日志关联
if appErr.ID == "" {
appErr.ID = uuid.NewString()
@@ -47,44 +51,48 @@ func (s *ResponseSender) logError(appErr *AppError, ctx fiber.Ctx) {
// 构造详细的错误级联链路(包含类型、状态、定位等)
chain := make([]map[string]any, 0, 4)
var e error = appErr
for e != nil {
currentErr := error(appErr)
for currentErr != nil {
entry := map[string]any{
"type": fmt.Sprintf("%T", e),
"error": e.Error(),
"type": fmt.Sprintf("%T", currentErr),
"error": currentErr.Error(),
}
switch v := e.(type) {
case *AppError:
entry["code"] = v.Code
entry["statusCode"] = v.StatusCode
if v.file != "" {
entry["file"] = v.file
var appErrItem *AppError
if errors.As(currentErr, &appErrItem) {
entry["code"] = appErrItem.Code
entry["statusCode"] = appErrItem.StatusCode
if appErrItem.file != "" {
entry["file"] = appErrItem.file
}
if len(v.params) > 0 {
entry["params"] = v.params
if len(appErrItem.params) > 0 {
entry["params"] = appErrItem.params
}
if v.sql != "" {
entry["sql"] = v.sql
if appErrItem.sql != "" {
entry["sql"] = appErrItem.sql
}
if v.ID != "" {
entry["id"] = v.ID
if appErrItem.ID != "" {
entry["id"] = appErrItem.ID
}
case *fiber.Error:
entry["statusCode"] = v.Code
entry["message"] = v.Message
}
var fiberErr *fiber.Error
if errors.As(currentErr, &fiberErr) {
entry["statusCode"] = fiberErr.Code
entry["message"] = fiberErr.Message
}
// GORM 常见错误归类标记
if errors.Is(e, gorm.ErrRecordNotFound) {
if errors.Is(currentErr, gorm.ErrRecordNotFound) {
entry["gorm"] = "record_not_found"
} else if errors.Is(e, gorm.ErrDuplicatedKey) {
} else if errors.Is(currentErr, gorm.ErrDuplicatedKey) {
entry["gorm"] = "duplicated_key"
} else if errors.Is(e, gorm.ErrInvalidTransaction) {
} else if errors.Is(currentErr, gorm.ErrInvalidTransaction) {
entry["gorm"] = "invalid_transaction"
}
chain = append(chain, entry)
e = errors.Unwrap(e)
currentErr = errors.Unwrap(currentErr)
}
root := chain[len(chain)-1]["error"]
@@ -100,7 +108,7 @@ func (s *ResponseSender) logError(appErr *AppError, ctx fiber.Ctx) {
fullPath = fmt.Sprintf("%s?%s", path, query)
}
fields := log.Fields{
fields := logrus.Fields{
"id": appErr.ID,
"code": appErr.Code,
"statusCode": appErr.StatusCode,
@@ -131,7 +139,7 @@ func (s *ResponseSender) logError(appErr *AppError, ctx fiber.Ctx) {
}
}
logEntry := log.WithFields(fields)
logEntry := logrus.WithFields(fields)
if appErr.originalErr != nil {
logEntry = logEntry.WithError(appErr.originalErr)
@@ -148,16 +156,28 @@ func (s *ResponseSender) logError(appErr *AppError, ctx fiber.Ctx) {
}
// sendResponse 发送响应
func (s *ResponseSender) sendResponse(ctx fiber.Ctx, appErr *AppError) error {
func (sender *ResponseSender) sendResponse(ctx fiber.Ctx, appErr *AppError) error {
contentType := utils.ToLower(utils.UnsafeString(ctx.Request().Header.ContentType()))
contentType = binder.FilterFlags(utils.ParseVendorSpecificContentType(contentType))
switch contentType {
case fiber.MIMETextXML, fiber.MIMEApplicationXML:
return ctx.Status(appErr.StatusCode).XML(appErr)
if err := ctx.Status(appErr.StatusCode).XML(appErr); err != nil {
return fmt.Errorf("send xml response: %w", err)
}
return nil
case fiber.MIMETextHTML, fiber.MIMETextPlain:
return ctx.Status(appErr.StatusCode).SendString(appErr.Message)
if err := ctx.Status(appErr.StatusCode).SendString(appErr.Message); err != nil {
return fmt.Errorf("send text response: %w", err)
}
return nil
default:
return ctx.Status(appErr.StatusCode).JSON(appErr)
if err := ctx.Status(appErr.StatusCode).JSON(appErr); err != nil {
return fmt.Errorf("send json response: %w", err)
}
return nil
}
}