diff --git a/backend/internal/controllers/download.go b/backend/internal/controllers/download.go index 09ea53e..edbfdb9 100644 --- a/backend/internal/controllers/download.go +++ b/backend/internal/controllers/download.go @@ -2,7 +2,6 @@ package controllers import ( "backend/internal/utils" - "errors" "fmt" "pkg/models" u "pkg/utils" @@ -21,7 +20,7 @@ type DownloadShareClaims struct { func DownloadShare(c *echo.Context) error { token := c.FormValue("token") if token == "" { - return utils.HTTPErrorHandler(c, errors.New("缺少token")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } claims := DownloadShareClaims{} t, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { @@ -31,7 +30,7 @@ func DownloadShare(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if !t.Valid { - return utils.HTTPErrorHandler(c, errors.New("token格式错误")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } shareInfo, _ := models.GetRedisShareInfo(claims.ShareId) @@ -60,7 +59,7 @@ func VaildateShare(c *echo.Context) error { } if r.ShareId == "" { - return utils.HTTPErrorHandler(c, errors.New("缺少分享ID")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } shareInfo, err := models.GetRedisShareInfo(r.ShareId) @@ -68,23 +67,23 @@ func VaildateShare(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if shareInfo == nil { - return utils.HTTPErrorHandler(c, errors.New("分享不存在")) + return utils.HTTPErrorHandler(c, ErrShareNotFound) } if shareInfo.Password != "" { if r.Password == "" { - return utils.HTTPErrorHandler(c, errors.New("缺少分享密码")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } hash, err := utils.GeneratePasswordHash(r.Password) if err != nil { return utils.HTTPErrorHandler(c, err) } if hash != shareInfo.Password { - return utils.HTTPErrorHandler(c, errors.New("分享密码错误")) + return utils.HTTPErrorHandler(c, ErrInvalidSharePassword) } } // 如果下载次数为0,则设置为-1 防止空值问题 if shareInfo.ViewNum < 1 { - return utils.HTTPErrorHandler(c, errors.New("下载次数不足")) + return utils.HTTPErrorHandler(c, ErrInsufficientDownloadQuota) } downloadWindow := u.GetEnvWithDefault("share.download_window", "12") token := jwt.NewWithClaims(jwt.SigningMethodHS256, DownloadShareClaims{ @@ -105,10 +104,10 @@ func VaildateShare(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if fileInfo == nil { - return utils.HTTPErrorHandler(c, errors.New("分享文件不存在")) + return utils.HTTPErrorHandler(c, ErrShareFileNotFound) } if fileInfo.FileType != models.FileTypeUpload { - return utils.HTTPErrorHandler(c, errors.New("分享文件状态错误")) + return utils.HTTPErrorHandler(c, ErrInvalidShareFileState) } } // download_nums 必须放在创建token的时候减掉,不然多线程下载会导致多次减掉 diff --git a/backend/internal/controllers/errors.go b/backend/internal/controllers/errors.go new file mode 100644 index 0000000..bd290dc --- /dev/null +++ b/backend/internal/controllers/errors.go @@ -0,0 +1,30 @@ +package controllers + +import "errors" + +var ( + // 通用错误(参数校验失败) + ErrInvalidRequest = errors.New("InvalidRequest") // 调用接口参数错误 + + // 任务相关 + ErrTaskNotFound = errors.New("TaskNotFound") // 任务不存在 + ErrTaskExpired = errors.New("TaskExpired") // 任务已过期 + + // 文件上传相关 + ErrInsufficientStorage = errors.New("InsufficientStorage") // 存储空间不足 + ErrUploadTaskExpired = errors.New("UploadTaskExpired") // 上传任务已过期 + ErrInvalidUploadTaskState = errors.New("InvalidUploadTaskState") // 上传任务状态错误 + ErrInvalidFileSliceIndex = errors.New("InvalidFileSliceIndex") // 文件切片索引错误 + ErrInvalidFileSliceSize = errors.New("InvalidFileSliceSize") // 文件切片大小错误 + ErrIncompleteFileSlices = errors.New("IncompleteFileSlices") // 文件切片不完整 + ErrFileMD5Mismatch = errors.New("FileMD5Mismatch") // 文件MD5不一致 + + // 分享相关 + ErrShareFileNotFound = errors.New("ShareFileNotFound") // 分享文件不存在 + ErrInvalidShareFileState = errors.New("InvalidShareFileState") // 分享文件状态错误 + ErrShareNotFound = errors.New("ShareNotFound") // 分享不存在 + + // 下载相关 + ErrInvalidSharePassword = errors.New("InvalidSharePassword") // 分享密码错误 + ErrInsufficientDownloadQuota = errors.New("InsufficientDownloadQuota") // 下载次数不足 +) diff --git a/backend/internal/controllers/file.go b/backend/internal/controllers/file.go index 63e5eb0..0fb27d5 100644 --- a/backend/internal/controllers/file.go +++ b/backend/internal/controllers/file.go @@ -4,7 +4,6 @@ import ( "backend/internal/services" "backend/internal/utils" "encoding/json" - "errors" "math" "mime/multipart" "os" @@ -25,7 +24,7 @@ func CreateUploadTask(c *echo.Context) error { } if r.FileSize == 0 || r.MimeType == "" || r.FileHash == "" { - return utils.HTTPErrorHandler(c, errors.New("调用接口参数错误")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } fileId := u.GetFileId(r.FileHash, r.FileSize) fileInfo, err := models.GetRedisFileInfo(fileId) @@ -71,7 +70,7 @@ func CreateUploadTask(c *echo.Context) error { totalSize += fileInfo.FileSize } if totalSize+r.FileSize > int64(maxStorageSize) { - return utils.HTTPErrorHandler(c, errors.New("存储空间不足")) + return utils.HTTPErrorHandler(c, ErrInsufficientStorage) } ChunkSize := int64(0.25 * 1024 * 1024) @@ -125,7 +124,7 @@ func UploadFileSlice(c *echo.Context) error { } if r.FileId == "" || r.FileIndex == 0 || r.FileSlice == nil { - return utils.HTTPErrorHandler(c, errors.New("调用接口参数错误")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } fileInfo, err := models.GetRedisFileInfo(r.FileId) if err != nil { @@ -134,18 +133,18 @@ func UploadFileSlice(c *echo.Context) error { now := time.Now().Unix() if fileInfo.CreatedAt+fileInfo.Expire < now { - return utils.HTTPErrorHandler(c, errors.New("上传任务已过期")) + return utils.HTTPErrorHandler(c, ErrUploadTaskExpired) } if fileInfo.FileType != models.FileTypeInit { - return utils.HTTPErrorHandler(c, errors.New("上传任务状态错误")) + return utils.HTTPErrorHandler(c, ErrInvalidUploadTaskState) } if r.FileIndex > ((fileInfo.FileSize / fileInfo.ChunkSize) + 1) { - return utils.HTTPErrorHandler(c, errors.New("文件切片索引错误")) + return utils.HTTPErrorHandler(c, ErrInvalidFileSliceIndex) } if r.FileSlice.Size > fileInfo.ChunkSize { - return utils.HTTPErrorHandler(c, errors.New("文件切片大小错误")) + return utils.HTTPErrorHandler(c, ErrInvalidFileSliceSize) } // 打开文件 @@ -180,7 +179,7 @@ func FinishUploadTask(c *echo.Context) error { } if r.FileId == "" { - return utils.HTTPErrorHandler(c, errors.New("文件ID不能为空")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } fileInfo, err := models.GetRedisFileInfo(r.FileId) @@ -189,12 +188,12 @@ func FinishUploadTask(c *echo.Context) error { } if fileInfo.FileType != models.FileTypeInit { - return utils.HTTPErrorHandler(c, errors.New("上传任务状态错误")) + return utils.HTTPErrorHandler(c, ErrInvalidUploadTaskState) } now := time.Now().Unix() if fileInfo.CreatedAt+fileInfo.Expire < now { - return utils.HTTPErrorHandler(c, errors.New("上传任务已过期")) + return utils.HTTPErrorHandler(c, ErrUploadTaskExpired) } uploadPath, err := u.GetUploadDirPath() @@ -208,7 +207,7 @@ func FinishUploadTask(c *echo.Context) error { } if len(fileSliceList) != int(math.Ceil(float64(fileInfo.FileSize)/float64(fileInfo.ChunkSize))) { - return utils.HTTPErrorHandler(c, errors.New("文件切片不完整")) + return utils.HTTPErrorHandler(c, ErrIncompleteFileSlices) } // 最终合并后的文件路径 @@ -236,7 +235,7 @@ func FinishUploadTask(c *echo.Context) error { if file_hash != fileInfo.FileHash { file.Close() os.Remove(mergeFilePath) - return utils.HTTPErrorHandler(c, errors.New("文件MD5不一致")) + return utils.HTTPErrorHandler(c, ErrFileMD5Mismatch) } defer file.Close() // 更新文件信息 diff --git a/backend/internal/controllers/share.go b/backend/internal/controllers/share.go index b6a6426..3103820 100644 --- a/backend/internal/controllers/share.go +++ b/backend/internal/controllers/share.go @@ -3,7 +3,6 @@ package controllers import ( "backend/internal/utils" "encoding/json" - "errors" "pkg/models" u "pkg/utils" "strings" @@ -41,11 +40,11 @@ func CreateShareInfo(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if r.Config.ExpireAt < 1 { - return utils.HTTPErrorHandler(c, errors.New("非法的分享过期时间")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } ExpireTime := time.Now().Add(time.Duration(r.Config.ExpireAt) * time.Minute) if r.Data == "" || (r.Type != models.ShareTypeFile && r.Type != models.ShareTypeText) || ExpireTime.Before(time.Now()) || r.Config.ViewNum < 1 { - return utils.HTTPErrorHandler(c, errors.New("调用接口参数错误")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } id, err := gonanoid.New() @@ -59,10 +58,10 @@ func CreateShareInfo(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if fileInfo == nil { - return utils.HTTPErrorHandler(c, errors.New("分享文件不存在")) + return utils.HTTPErrorHandler(c, ErrShareFileNotFound) } if fileInfo.FileType != models.FileTypeUpload { - return utils.HTTPErrorHandler(c, errors.New("分享文件状态错误")) + return utils.HTTPErrorHandler(c, ErrInvalidShareFileState) } } password := "" @@ -151,7 +150,7 @@ type GetShareProps struct { func GetShareInfo(c *echo.Context) error { shareId := c.Param("id") if shareId == "" { - return utils.HTTPErrorHandler(c, errors.New("缺少分享ID")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } shareInfo, err := models.GetRedisShareInfo(shareId) @@ -159,7 +158,7 @@ func GetShareInfo(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if shareInfo == nil || shareInfo.ViewNum < 1 { - return utils.HTTPErrorHandler(c, errors.New("分享不存在")) + return utils.HTTPErrorHandler(c, ErrShareNotFound) } if shareInfo.Type == models.ShareTypeFile { @@ -168,10 +167,10 @@ func GetShareInfo(c *echo.Context) error { return utils.HTTPErrorHandler(c, err) } if fileInfo == nil { - return utils.HTTPErrorHandler(c, errors.New("分享文件不存在")) + return utils.HTTPErrorHandler(c, ErrShareFileNotFound) } if fileInfo.FileType != models.FileTypeUpload { - return utils.HTTPErrorHandler(c, errors.New("分享文件状态错误")) + return utils.HTTPErrorHandler(c, ErrInvalidShareFileState) } return utils.HTTPSuccessHandler(c, map[string]any{ "id": shareId, @@ -200,14 +199,14 @@ func GetShareInfo(c *echo.Context) error { func GetShareByPickupCode(c *echo.Context) error { pickupCode := c.Param("code") if pickupCode == "" { - return utils.HTTPErrorHandler(c, errors.New("缺少提取码")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } shareId, err := models.GetRedisPickupData(strings.ToUpper(pickupCode)) if err != nil { return utils.HTTPErrorHandler(c, err) } if shareId == "" { - return utils.HTTPErrorHandler(c, errors.New("分享不存在")) + return utils.HTTPErrorHandler(c, ErrShareNotFound) } return utils.HTTPSuccessHandler(c, map[string]any{ "share_id": shareId, diff --git a/backend/internal/controllers/task.go b/backend/internal/controllers/task.go index f8f8f7a..4c3b17c 100644 --- a/backend/internal/controllers/task.go +++ b/backend/internal/controllers/task.go @@ -3,7 +3,6 @@ package controllers import ( "backend/internal/controllers/task" "backend/internal/utils" - "errors" "pkg/models" u "pkg/utils" @@ -19,11 +18,11 @@ var handleTaskMap = map[string]func(c *echo.Context) ([]byte, error){ func CreateTask(c *echo.Context) error { taskType := c.Param("type") if taskType == "" { - return utils.HTTPErrorHandler(c, errors.New("调用接口参数错误")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } handleTask, ok := handleTaskMap[taskType] if !ok { - return utils.HTTPErrorHandler(c, errors.New("任务不存在")) + return utils.HTTPErrorHandler(c, ErrTaskNotFound) } json, err := handleTask(c) if err != nil { @@ -44,7 +43,7 @@ func CreateTask(c *echo.Context) error { func GetTask(c *echo.Context) error { taskId := c.Param("id") if taskId == "" { - return utils.HTTPErrorHandler(c, errors.New("调用接口参数错误")) + return utils.HTTPErrorHandler(c, ErrInvalidRequest) } taskInfo, err := models.GetRedisTaskInfo(taskId) @@ -56,7 +55,7 @@ func GetTask(c *echo.Context) error { queneTaskInfo, err := client.GetTaskInfo("default", taskId) if err != nil { - return utils.HTTPErrorHandler(c, errors.New("任务已过期")) + return utils.HTTPErrorHandler(c, ErrTaskExpired) } stateMap := map[asynq.TaskState]string{ asynq.TaskStateActive: "processing", diff --git a/backend/internal/controllers/task/errors.go b/backend/internal/controllers/task/errors.go new file mode 100644 index 0000000..759459f --- /dev/null +++ b/backend/internal/controllers/task/errors.go @@ -0,0 +1,7 @@ +package task + +import "errors" + +var ( + ErrInvalidRequest = errors.New("InvalidRequest") +) diff --git a/backend/internal/controllers/task/image.go b/backend/internal/controllers/task/image.go index 257baae..bee32f6 100644 --- a/backend/internal/controllers/task/image.go +++ b/backend/internal/controllers/task/image.go @@ -2,7 +2,6 @@ package task import ( "encoding/json" - "errors" "github.com/labstack/echo/v5" ) @@ -17,7 +16,7 @@ func HandleImageCompress(c *echo.Context) ([]byte, error) { return nil, err } if r.FileId == "" { - return nil, errors.New("调用接口参数错误") + return nil, ErrInvalidRequest } json, err := json.Marshal(map[string]any{ "file_id": r.FileId, @@ -39,11 +38,12 @@ func HandleImageConvert(c *echo.Context) ([]byte, error) { if err := c.Bind(r); err != nil { return nil, err } - if r.FileId == "" { - return nil, errors.New("调用接口参数错误") + if r.FileId == "" || r.TargetExt == "" { + return nil, ErrInvalidRequest } json, err := json.Marshal(map[string]any{ - "file_id": r.FileId, + "file_id": r.FileId, + "target_ext": r.TargetExt, }) if err != nil { return nil, err