refactor(backend): replace error handling with predefined error variables for consistency across download and upload tasks

This commit is contained in:
keven1024
2026-02-27 15:10:59 +08:00
parent f1dec39851
commit fe6c832275
7 changed files with 77 additions and 44 deletions

View File

@@ -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的时候减掉不然多线程下载会导致多次减掉

View File

@@ -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") // 下载次数不足
)

View File

@@ -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()
// 更新文件信息

View File

@@ -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,

View File

@@ -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",

View File

@@ -0,0 +1,7 @@
package task
import "errors"
var (
ErrInvalidRequest = errors.New("InvalidRequest")
)

View File

@@ -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