Gin错误处理中间件示例
参考示例:
// getValidatorErrMsg 获得友好的validator错误信息 func getValidatorErrMsg(fieldErr validator.FieldError) string { switch fieldErr.Tag() { case "required": return fmt.Sprintf("%s 是必填字段", fieldErr.Field()) case "min": return fmt.Sprintf("%s 最小长度为 %s", fieldErr.Field(), fieldErr.Param()) case "max": return fmt.Sprintf("%s 最大长度为 %s", fieldErr.Field(), fieldErr.Param()) case "email": return fmt.Sprintf("%s 必须是有效的电子邮件地址", fieldErr.Field()) case "eqfield": return fmt.Sprintf("%s 必须与 %s 相同", fieldErr.Field(), fieldErr.Param()) case "gt": return fmt.Sprintf("%s 必须大于 %s", fieldErr.Field(), fieldErr.Param()) case "gte": return fmt.Sprintf("%s 必须大于等于 %s", fieldErr.Field(), fieldErr.Param()) case "lt": return fmt.Sprintf("%s 必须小于 %s", fieldErr.Field(), fieldErr.Param()) case "lte": return fmt.Sprintf("%s 必须小于等于 %s", fieldErr.Field(), fieldErr.Param()) case "eq": return fmt.Sprintf("%s 必须等于 %s", fieldErr.Field(), fieldErr.Param()) case "len": return fmt.Sprintf("%s 长度必须等于 %s", fieldErr.Field(), fieldErr.Param()) default: return fmt.Sprintf("%s 验证失败 (%s)", fieldErr.Field(), fieldErr.Tag()) } } // ServerErrorHandleMiddleware 错误处理中间件,处理后续中间件或路由的错误,需放到最前面 func ServerErrorHandleMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 先进入后续路由/中间件 c.Next() if len(c.Errors) == 0 { // 无错误 return } if len(c.Errors) > 1 { // 存在多个错误,判定为错误处理不合规 // 整个请求过程中,触发错误应该立即结束并返回 c.JSON(http.StatusInternalServerError, gin.H{ "detail": "错误处理不合规", }) return } // 开始包装错误 finalErr := c.Errors[0] msgSlice := make([]string, 0) var finalCode int if validatorErrs, ok := finalErr.Err.(validator.ValidationErrors); ok { // 返回的是validator触发的错误 // validator会把错误收集在[]FieldError中 // 收集错误文本信息 for _, err := range validatorErrs { msg := getValidatorErrMsg(err) msgSlice = append(msgSlice, msg) } // 设定错误状态码 finalCode = http.StatusBadRequest } else if mError, ok := merror.IsMError(finalErr.Err); ok { // 返回的是自定义错误 msg := mError.Detail msgSlice = append(msgSlice, msg) finalCode = mError.Code } else { // 其他错误 msgSlice = append(msgSlice, "未正确处理错误") finalCode = http.StatusInternalServerError } // 拼接错误文本 detail := strings.Join(msgSlice, " | ") c.JSON(finalCode, gin.H{ "detail": detail, }) return } }
浙公网安备 33010602011771号