Files
godoxy-yusing/internal/api/v1/file/validate.go
yusing 6da7227f9b refactor(errs): migrate from gperr.Error to standard Go error interface
This is a large-scale refactoring across the codebase that replaces the custom
`gperr.Error` type with Go's standard `error` interface. The changes include:

- Replacing `gperr.Error` return types with `error` in function signatures
- Using `errors.New()` and `fmt.Errorf()` instead of `gperr.New()` and `gperr.Errorf()`
- Using `%w` format verb for error wrapping instead of `.With()` method
- Replacing `gperr.Subject()` calls with `gperr.PrependSubject()`
- Converting error logging from `gperr.Log*()` functions to zerolog's `.Err().Msg()` pattern
- Update NewLogger to handle multiline error message
- Updating `goutils` submodule to latest commit

This refactoring aligns with Go idioms and removes the dependency on
custom error handling abstractions in favor of standard library patterns.
2026-02-08 12:07:36 +08:00

65 lines
1.9 KiB
Go

package fileapi
import (
"net/http"
"github.com/gin-gonic/gin"
config "github.com/yusing/godoxy/internal/config/types"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/route/provider"
apitypes "github.com/yusing/goutils/apitypes"
gperr "github.com/yusing/goutils/errs"
)
type ValidateFileRequest struct {
FileType FileType `form:"type" validate:"required,oneof=config provider middleware"`
} // @name ValidateFileRequest
// @x-id "validate"
// @BasePath /api/v1
// @Summary Validate file
// @Description Validate file
// @Tags file
// @Accept application/yaml
// @Produce json
// @Param type query FileType true "Type"
// @Param file body string true "File content"
// @Success 200 {object} apitypes.SuccessResponse "File validated"
// @Failure 400 {object} apitypes.ErrorResponse "Bad request"
// @Failure 403 {object} apitypes.ErrorResponse "Forbidden"
// @Failure 417 {object} any "Validation failed"
// @Failure 500 {object} apitypes.ErrorResponse "Internal server error"
// @Router /file/validate [post]
func Validate(c *gin.Context) {
var request ValidateFileRequest
if err := c.ShouldBindQuery(&request); err != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
return
}
content, err := c.GetRawData()
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to read file"))
return
}
c.Request.Body.Close()
if valErr := validateFile(request.FileType, content); valErr != nil {
c.JSON(http.StatusExpectationFailed, valErr)
return
}
c.JSON(http.StatusOK, apitypes.Success("file validated"))
}
func validateFile(fileType FileType, content []byte) error {
switch fileType {
case FileTypeConfig:
return config.Validate(content)
case FileTypeMiddleware:
errs := gperr.NewBuilder("middleware errors")
middleware.BuildMiddlewaresFromYAML("", content, &errs)
return errs.Error()
}
return provider.Validate(content)
}