u
This commit is contained in:
1 parent
d1b1aafc57
commit
0f1604c709
58 files changed
+15476
-25
No files matched your search
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func Test(c *router.Context) {
|
||||
|
||||
|
||||
dbClient := db.NewClient(c)
|
||||
if dbClient == nil {
|
||||
return
|
||||
@@ -16,6 +16,7 @@ func Test(c *router.Context) {
|
||||
|
||||
sqlStr := "SELECT id, name FROM user"
|
||||
rows, err := dbClient.QueryRows(sqlStr)
|
||||
|
||||
if err != nil {
|
||||
c.AddError(err)
|
||||
return
|
||||
|
||||
@@ -2,22 +2,26 @@ package middleware
|
||||
|
||||
import (
|
||||
"base-framework/pkg/router"
|
||||
"base-framework/pkg/utils/response"
|
||||
"log"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Error 全局业务错误处理中间件
|
||||
func Error() router.HandlerFunc {
|
||||
return func(c *router.Context) {
|
||||
// 执行业务逻辑
|
||||
c.Next()
|
||||
c.Next() // 执行后续 Handler
|
||||
|
||||
// 统一处理错误
|
||||
if errs := c.Errors(); len(errs) > 0 {
|
||||
errs := c.Errors()
|
||||
if len(errs) > 0 {
|
||||
lastErr := errs[len(errs)-1]
|
||||
log.Printf("[ERROR] %v", lastErr)
|
||||
|
||||
response.Error(c).Send()
|
||||
// 打印错误信息和堆栈
|
||||
fmt.Printf("[ERROR] %v\nStack trace:\n%s\n", lastErr.Error(), lastErr.StackTrace())
|
||||
|
||||
// 返回前端安全信息
|
||||
c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"code": "FAIL",
|
||||
"message": lastErr.Error(),
|
||||
})
|
||||
c.Abort()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"base-framework/pkg/router"
|
||||
"base-framework/pkg/utils/response"
|
||||
"log"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
func Recovery() router.HandlerFunc {
|
||||
return func(c *router.Context) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
// 打印 panic 信息和堆栈
|
||||
log.Printf("[Recovery] panic recovered: %v\n%s", err, debug.Stack())
|
||||
|
||||
response.Error(c).Send()
|
||||
}
|
||||
}()
|
||||
|
||||
// 调用后续 handler
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"base-framework/pkg/utils"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
@@ -125,7 +126,7 @@ func (c *Context) Get(key string) (interface{}, bool) {
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// AddError 只记录错误对象
|
||||
// AddError 记录错误,自动包装 StackError
|
||||
func (c *Context) AddError(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
@@ -134,19 +135,23 @@ func (c *Context) AddError(err error) {
|
||||
if c.keys == nil {
|
||||
c.keys = make(map[string]interface{})
|
||||
}
|
||||
|
||||
if _, exists := c.keys["errors"]; !exists {
|
||||
c.keys["errors"] = []error{}
|
||||
c.keys["errors"] = []*utils.StackError{}
|
||||
}
|
||||
c.keys["errors"] = append(c.keys["errors"].([]error), err)
|
||||
|
||||
// 统一生成堆栈
|
||||
se := utils.WrapWithStack(err)
|
||||
c.keys["errors"] = append(c.keys["errors"].([]*utils.StackError), se)
|
||||
}
|
||||
|
||||
// Errors 获取所有错误
|
||||
func (c *Context) Errors() []error {
|
||||
// Errors 返回 []*utils.StackError
|
||||
func (c *Context) Errors() []*utils.StackError {
|
||||
if c.keys == nil {
|
||||
return nil
|
||||
}
|
||||
if errs, exists := c.keys["errors"]; exists {
|
||||
return errs.([]error)
|
||||
return errs.([]*utils.StackError)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -12,13 +11,10 @@ func (c *Client) QueryRows(query string, args ...any) ([]map[string]any, error)
|
||||
|
||||
rows, err := c.Conn.Query(query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, err // 不加 debug.Stack()
|
||||
}
|
||||
defer func(rows *sql.Rows) {
|
||||
_ = rows.Close()
|
||||
}(rows)
|
||||
defer rows.Close()
|
||||
|
||||
// 获取列名
|
||||
columns, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -26,7 +22,6 @@ func (c *Client) QueryRows(query string, args ...any) ([]map[string]any, error)
|
||||
|
||||
results := make([]map[string]any, 0)
|
||||
for rows.Next() {
|
||||
// 为每列创建一个接口值的 slice
|
||||
values := make([]any, len(columns))
|
||||
valuePtrs := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package utils
|
||||
|
||||
import "runtime/debug"
|
||||
|
||||
// StackError 保存原始错误和堆栈
|
||||
type StackError struct {
|
||||
err error
|
||||
stack string
|
||||
}
|
||||
|
||||
// 实现 error 接口
|
||||
func (s *StackError) Error() string {
|
||||
if s.err == nil {
|
||||
return ""
|
||||
}
|
||||
return s.err.Error()
|
||||
}
|
||||
|
||||
// StackTrace 返回堆栈信息
|
||||
func (s *StackError) StackTrace() string {
|
||||
return s.stack
|
||||
}
|
||||
|
||||
// WrapWithStack 给错误附加堆栈,如果已经是 StackError 则直接返回
|
||||
func WrapWithStack(err error) *StackError {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if se, ok := err.(*StackError); ok {
|
||||
return se
|
||||
}
|
||||
|
||||
return &StackError{
|
||||
err: err,
|
||||
stack: string(debug.Stack()),
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ type Result struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
Error *ErrorInfo `json:"error,omitempty"`
|
||||
Error ErrorInfo `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -92,7 +92,7 @@ func (b *Builder) Data(data interface{}) *Builder {
|
||||
}
|
||||
|
||||
// ErrorInfo 设置错误信息
|
||||
func (b *Builder) ErrorInfo(err *ErrorInfo) *Builder {
|
||||
func (b *Builder) ErrorInfo(err ErrorInfo) *Builder {
|
||||
b.result.Error = err
|
||||
return b
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user