refactor validation error and user register response

This commit is contained in:
nochill 2023-09-13 11:30:15 +07:00
parent dfe00f8359
commit e854f2e81f
2 changed files with 55 additions and 39 deletions

View File

@ -1,6 +1,44 @@
package api package api
import "github.com/gin-gonic/gin" import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
type APIValidationError struct {
Field string `json:"field"`
Msg string `json:"msg"`
}
func validationErrorMsg(field string, param string, tag string) string {
switch tag {
case "min":
return fmt.Sprintf("%s character min %s", field, param)
case "required":
return fmt.Sprintf("%s is %s", field, tag)
default:
return fmt.Sprintf("%s %s", field, tag)
}
}
func ValidationErrorResponse(err error) gin.H {
var ves validator.ValidationErrors
var temp []APIValidationError
if errors.As(err, &ves) {
out := make([]APIValidationError, len(ves))
for i, ve := range ves {
out[i] = APIValidationError{ve.Field(), validationErrorMsg(ve.Field(), ve.Param(), ve.ActualTag())}
}
temp = out
}
return gin.H{
"message": "Validation error",
"errors": temp,
}
}
func ErrorResponse(err error, msg string) gin.H { func ErrorResponse(err error, msg string) gin.H {
return gin.H{ return gin.H{

View File

@ -2,14 +2,12 @@ package api
import ( import (
"database/sql" "database/sql"
"errors"
"fmt"
"net/http" "net/http"
"time"
db "git.nochill.in/nochill/hiling_go/db/sqlc" db "git.nochill.in/nochill/hiling_go/db/sqlc"
"git.nochill.in/nochill/hiling_go/util" "git.nochill.in/nochill/hiling_go/util"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/lib/pq" "github.com/lib/pq"
) )
@ -25,40 +23,19 @@ type createUserResponse struct {
BannedAt sql.NullTime `json:"banned_at"` BannedAt sql.NullTime `json:"banned_at"`
BannedUntil sql.NullTime `json:"banned_until"` BannedUntil sql.NullTime `json:"banned_until"`
BanReason string `json:"ban_reason"` BanReason string `json:"ban_reason"`
IsPermaban sql.NullBool `json:"is_permaban"` IsPermaban bool `json:"is_permaban"`
IsAdmin sql.NullBool `json:"is_admin"` IsAdmin bool `json:"is_admin"`
IsCritics sql.NullBool `json:"is_critics"` IsCritics bool `json:"is_critics"`
IsVerified sql.NullBool `json:"is_verified"` IsVerified bool `json:"is_verified"`
CreatedAt sql.NullTime `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt sql.NullTime `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
}
type ApiError struct {
Field string
Msg string
}
func msgForTag(field string, param string, tag string) string {
switch tag {
case "min":
return fmt.Sprintf("%s character min %s", field, param)
default:
return fmt.Sprintf("%s %s", field, tag)
}
} }
func (server *Server) createUser(ctx *gin.Context) { func (server *Server) createUser(ctx *gin.Context) {
var req createUserRequest var req createUserRequest
if err := ctx.ShouldBindJSON(&req); err != nil { if err := ctx.ShouldBindJSON(&req); err != nil {
if err != nil { if err != nil {
var ve validator.ValidationErrors ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
if errors.As(err, &ve) {
out := make([]ApiError, len(ve))
for i, fe := range ve {
out[i] = ApiError{fe.Field(), msgForTag(fe.Field(), fe.Param(), fe.Tag())}
}
ctx.JSON(http.StatusBadRequest, gin.H{"errors": out})
}
return return
} }
} }
@ -79,7 +56,8 @@ func (server *Server) createUser(ctx *gin.Context) {
if pqErr, ok := err.(*pq.Error); ok { if pqErr, ok := err.(*pq.Error); ok {
switch pqErr.Code.Name() { switch pqErr.Code.Name() {
case "foreign_key_violation", "unique_violation": case "foreign_key_violation", "unique_violation":
ctx.JSON(http.StatusConflict, ErrorResponse(err, "Something went wrong while try to save")) ctx.JSON(http.StatusConflict, ErrorResponse(err, "Username already used"))
return
} }
} }
@ -94,12 +72,12 @@ func (server *Server) createUser(ctx *gin.Context) {
BannedAt: sql.NullTime{Valid: user.BannedAt.Valid, Time: user.BannedAt.Time}, BannedAt: sql.NullTime{Valid: user.BannedAt.Valid, Time: user.BannedAt.Time},
BannedUntil: sql.NullTime{Valid: user.BannedUntil.Valid, Time: user.BannedUntil.Time}, BannedUntil: sql.NullTime{Valid: user.BannedUntil.Valid, Time: user.BannedUntil.Time},
BanReason: user.BanReason.String, BanReason: user.BanReason.String,
IsPermaban: user.IsPermaban, IsPermaban: user.IsPermaban.Bool,
IsAdmin: user.IsAdmin, IsAdmin: user.IsAdmin.Bool,
IsCritics: user.IsCritics, IsCritics: user.IsCritics.Bool,
IsVerified: user.IsVerified, IsVerified: user.IsVerified.Bool,
CreatedAt: sql.NullTime{Valid: true, Time: user.CreatedAt.Time}, CreatedAt: user.CreatedAt.Time,
UpdatedAt: sql.NullTime{Valid: true, Time: user.UpdatedAt.Time}, UpdatedAt: user.UpdatedAt.Time,
} }
ctx.JSON(http.StatusOK, res) ctx.JSON(http.StatusOK, res)