From 84703a897187ffeba1ce82170935b7261ad56da3 Mon Sep 17 00:00:00 2001 From: zicla Date: Fri, 30 Nov 2018 19:38:46 +0800 Subject: [PATCH] Refine panic framework. --- rest/base_controller.go | 16 ------------- rest/bean.go | 28 ++++++++++++++++------ rest/footprint_controller.go | 12 ++++------ rest/image_cache_controller.go | 10 ++++---- rest/matter_controller.go | 44 +++++++++++++++++----------------- rest/matter_service.go | 14 ++++------- rest/router.go | 38 ++++++++++++----------------- rest/user_controller.go | 26 ++++++++++---------- rest/web_error.go | 10 -------- rest/web_result.go | 3 +++ 10 files changed, 88 insertions(+), 113 deletions(-) delete mode 100644 rest/web_error.go diff --git a/rest/base_controller.go b/rest/base_controller.go index 9044d25..1591a17 100644 --- a/rest/base_controller.go +++ b/rest/base_controller.go @@ -117,22 +117,6 @@ func (this *BaseController) Success(data interface{}) *WebResult { return webResult } -//返回错误的结果。 -func (this *BaseController) Error(err interface{}) *WebResult { - var webResult *WebResult = nil - if value, ok := err.(string); ok { - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: value} - } else if _, ok := err.(int); ok { - webResult = ConstWebResult(CODE_WRAPPER_UNKNOWN) - } else if value, ok := err.(*WebResult); ok { - webResult = value - } else if value, ok := err.(error); ok { - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: value.Error()} - } else { - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: "服务器未知错误"} - } - return webResult -} //允许跨域请求 func (this *BaseController) allowCORS(writer http.ResponseWriter) { diff --git a/rest/bean.go b/rest/bean.go index 522aabf..8ef6b24 100644 --- a/rest/bean.go +++ b/rest/bean.go @@ -6,8 +6,7 @@ import ( type IBean interface { Init() - PanicError(err error); - PanicWebError(msg string, code int); + PanicError(err error) } type Bean struct { @@ -18,16 +17,31 @@ func (this *Bean) Init() { this.logger = LOGGER } -//处理错误的统一方法 +//处理错误的统一方法 可以省去if err!=nil 这段代码 func (this *Bean) PanicError(err error) { if err != nil { - panic(&WebError{Msg: err.Error(), Code: http.StatusInternalServerError}) + panic(err) } } -//处理错误的统一方法 -func (this *Bean) PanicWebError(msg string, httpStatusCode int) { - panic(&WebError{Msg: msg, Code: httpStatusCode}) +//请求参数有问题 +func (this *Bean) PanicBadRequest(msg string) { + panic(CustomWebResult(CODE_WRAPPER_BAD_REQUEST, msg)) +} + +//没有权限 +func (this *Bean) PanicUnauthorized(msg string) { + panic(CustomWebResult(CODE_WRAPPER_UNAUTHORIZED, msg)) +} + +//没有找到 +func (this *Bean) PanicNotFound(msg string) { + panic(CustomWebResult(CODE_WRAPPER_NOT_FOUND, msg)) +} + +//服务器内部出问题 +func (this *Bean) PanicServer(msg string) { + panic(CustomWebResult(CODE_WRAPPER_UNKNOWN, msg)) } //能找到一个user就找到一个 diff --git a/rest/footprint_controller.go b/rest/footprint_controller.go index 80c977d..d23cf78 100644 --- a/rest/footprint_controller.go +++ b/rest/footprint_controller.go @@ -46,7 +46,7 @@ func (this *FootprintController) Detail(writer http.ResponseWriter, request *htt uuid := request.FormValue("uuid") if uuid == "" { - return this.Error("图片缓存的uuid必填") + this.PanicBadRequest("图片缓存的uuid必填") } footprint := this.footprintService.Detail(uuid) @@ -112,18 +112,14 @@ func (this *FootprintController) Delete(writer http.ResponseWriter, request *htt uuid := request.FormValue("uuid") if uuid == "" { - return this.Error("图片缓存的uuid必填") + this.PanicBadRequest("uuid必填") } footprint := this.footprintDao.FindByUuid(uuid) - //判断图片缓存的所属人是否正确 - user := this.checkUser(writer, request) - if user.Role != USER_ROLE_ADMINISTRATOR && footprint.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + if footprint != nil { + this.footprintDao.Delete(footprint) } - this.footprintDao.Delete(footprint) - return this.Success("删除成功!") } diff --git a/rest/image_cache_controller.go b/rest/image_cache_controller.go index 1ca8af7..25838cb 100644 --- a/rest/image_cache_controller.go +++ b/rest/image_cache_controller.go @@ -48,7 +48,7 @@ func (this *ImageCacheController) Detail(writer http.ResponseWriter, request *ht uuid := request.FormValue("uuid") if uuid == "" { - return this.Error("图片缓存的uuid必填") + this.PanicBadRequest("图片缓存的uuid必填") } imageCache := this.imageCacheService.Detail(uuid) @@ -115,7 +115,7 @@ func (this *ImageCacheController) Delete(writer http.ResponseWriter, request *ht uuid := request.FormValue("uuid") if uuid == "" { - return this.Error("图片缓存的uuid必填") + this.PanicBadRequest("图片缓存的uuid必填") } imageCache := this.imageCacheDao.FindByUuid(uuid) @@ -123,7 +123,7 @@ func (this *ImageCacheController) Delete(writer http.ResponseWriter, request *ht //判断图片缓存的所属人是否正确 user := this.checkUser(writer, request) if user.Role != USER_ROLE_ADMINISTRATOR && imageCache.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } this.imageCacheDao.Delete(imageCache) @@ -136,7 +136,7 @@ func (this *ImageCacheController) DeleteBatch(writer http.ResponseWriter, reques uuids := request.FormValue("uuids") if uuids == "" { - return this.Error("图片缓存的uuids必填") + this.PanicBadRequest("图片缓存的uuids必填") } uuidArray := strings.Split(uuids, ",") @@ -148,7 +148,7 @@ func (this *ImageCacheController) DeleteBatch(writer http.ResponseWriter, reques //判断图片缓存的所属人是否正确 user := this.checkUser(writer, request) if user.Role != USER_ROLE_ADMINISTRATOR && imageCache.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } this.imageCacheDao.Delete(imageCache) diff --git a/rest/matter_controller.go b/rest/matter_controller.go index cc0fde9..d4bcb23 100644 --- a/rest/matter_controller.go +++ b/rest/matter_controller.go @@ -63,7 +63,7 @@ func (this *MatterController) Detail(writer http.ResponseWriter, request *http.R uuid := request.FormValue("uuid") if uuid == "" { - return this.Error("文件的uuid必填") + this.PanicBadRequest("文件的uuid必填") } matter := this.matterService.Detail(uuid) @@ -89,14 +89,14 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques name = strings.TrimSpace(name) //验证参数。 if name == "" { - return this.Error("name参数必填,并且不能全是空格") + this.PanicBadRequest("name参数必填,并且不能全是空格") } if len(name) > 200 { panic("name长度不能超过200") } if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { - return this.Error(`名称中不能包含以下特殊符号:< > | * ? / \`) + this.PanicBadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`) } userUuid := request.FormValue("userUuid") @@ -133,7 +133,7 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, puuid, true, name) if count > 0 { - return this.Error("【" + name + "】已经存在了,请使用其他名称。") + this.PanicBadRequest("【" + name + "】已经存在了,请使用其他名称。") } matter := &Matter{ @@ -240,7 +240,7 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R } else { puuid = request.FormValue("puuid") if puuid == "" { - return this.Error("puuid必填") + this.PanicBadRequest("puuid必填") } else { if puuid != "root" { //找出上一级的文件夹。 @@ -283,7 +283,7 @@ func (this *MatterController) Crawl(writer http.ResponseWriter, request *http.Re puuid := request.FormValue("puuid") if puuid == "" { - return this.Error("puuid必填") + this.PanicBadRequest("puuid必填") } else { if puuid != "root" { //找出上一级的文件夹。 @@ -317,7 +317,7 @@ func (this *MatterController) Delete(writer http.ResponseWriter, request *http.R uuid := request.FormValue("uuid") if uuid == "" { - return this.Error("文件的uuid必填") + this.PanicBadRequest("文件的uuid必填") } matter := this.matterDao.FindByUuid(uuid) @@ -325,7 +325,7 @@ func (this *MatterController) Delete(writer http.ResponseWriter, request *http.R //判断文件的所属人是否正确 user := this.checkUser(writer, request) if user.Role != USER_ROLE_ADMINISTRATOR && matter.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } this.matterDao.Delete(matter) @@ -338,7 +338,7 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h uuids := request.FormValue("uuids") if uuids == "" { - return this.Error("文件的uuids必填") + this.PanicBadRequest("文件的uuids必填") } uuidArray := strings.Split(uuids, ",") @@ -350,7 +350,7 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h //判断文件的所属人是否正确 user := this.checkUser(writer, request) if user.Role != USER_ROLE_ADMINISTRATOR && matter.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } this.matterDao.Delete(matter) @@ -368,10 +368,10 @@ func (this *MatterController) Rename(writer http.ResponseWriter, request *http.R //验证参数。 if name == "" { - return this.Error("name参数必填") + this.PanicBadRequest("name参数必填") } if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { - return this.Error(`名称中不能包含以下特殊符号:< > | * ? / \`) + this.PanicBadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`) } if len(name) > 200 { @@ -383,18 +383,18 @@ func (this *MatterController) Rename(writer http.ResponseWriter, request *http.R user := this.checkUser(writer, request) if user.Role != USER_ROLE_ADMINISTRATOR && matter.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } if name == matter.Name { - return this.Error("新名称和旧名称一样,操作失败!") + this.PanicBadRequest("新名称和旧名称一样,操作失败!") } //判断同级文件夹中是否有同名的文件 count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, matter.Puuid, matter.Dir, name) if count > 0 { - return this.Error("【" + name + "】已经存在了,请使用其他名称。") + this.PanicBadRequest("【" + name + "】已经存在了,请使用其他名称。") } matter.Name = name @@ -421,7 +421,7 @@ func (this *MatterController) ChangePrivacy(writer http.ResponseWriter, request //权限验证 user := this.checkUser(writer, request) if user.Role != USER_ROLE_ADMINISTRATOR && matter.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } matter.Privacy = privacy @@ -439,7 +439,7 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req var srcUuids []string //验证参数。 if srcUuidsStr == "" { - return this.Error("srcUuids参数必填") + this.PanicBadRequest("srcUuids参数必填") } else { srcUuids = strings.Split(srcUuidsStr, ",") } @@ -458,13 +458,13 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req //验证dest是否有问题 var destMatter *Matter if destUuid == "" { - return this.Error("destUuid参数必填") + this.PanicBadRequest("destUuid参数必填") } else { if destUuid != "root" { destMatter = this.matterService.Detail(destUuid) if user.Role != USER_ROLE_ADMINISTRATOR && destMatter.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } } } @@ -476,18 +476,18 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req srcMatter := this.matterDao.CheckByUuid(uuid) if user.Role != USER_ROLE_ADMINISTRATOR && srcMatter.UserUuid != user.Uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } if srcMatter.Puuid == destUuid { - return this.Error("没有进行移动,操作无效!") + this.PanicBadRequest("没有进行移动,操作无效!") } //判断同级文件夹中是否有同名的文件 count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, destUuid, srcMatter.Dir, srcMatter.Name) if count > 0 { - return this.Error("【" + srcMatter.Name + "】在目标文件夹已经存在了,操作失败。") + this.PanicBadRequest("【" + srcMatter.Name + "】在目标文件夹已经存在了,操作失败。") } //判断和目标文件夹是否是同一个主人。 diff --git a/rest/matter_service.go b/rest/matter_service.go index 85f8ac7..8c1e6e2 100644 --- a/rest/matter_service.go +++ b/rest/matter_service.go @@ -7,12 +7,12 @@ import ( "mime/multipart" "net/http" "net/textproto" + "net/url" "os" "regexp" "strconv" "strings" "time" - "net/url" ) //@Service @@ -451,7 +451,7 @@ func (this *MatterService) DownloadFile( //显示文件大小。 fileInfo, err := diskFile.Stat() if err != nil { - this.PanicWebError(err.Error(), http.StatusInternalServerError) + this.PanicServer("无法从磁盘中获取文件信息") } modifyTime := fileInfo.ModTime() @@ -486,8 +486,7 @@ func (this *MatterService) DownloadFile( ctype = http.DetectContentType(buf[:n]) _, err := diskFile.Seek(0, os.SEEK_SET) // rewind to output whole file if err != nil { - this.PanicWebError("无法准确定位文件", http.StatusInternalServerError) - return + this.PanicServer("无法准确定位文件") } } writer.Header().Set("Content-Type", ctype) @@ -503,9 +502,7 @@ func (this *MatterService) DownloadFile( if size >= 0 { ranges, err := this.parseRange(rangeReq, size) if err != nil { - panic("range header出错") - this.PanicWebError("range header error", http.StatusRequestedRangeNotSatisfiable) - return + panic(CustomWebResult(CODE_WRAPPER_RANGE_NOT_SATISFIABLE, "range header出错")) } if this.sumRangesSize(ranges) > size { // The total number of bytes in all the ranges @@ -529,8 +526,7 @@ func (this *MatterService) DownloadFile( // be sent using the multipart/byteranges media type." ra := ranges[0] if _, err := diskFile.Seek(ra.start, io.SeekStart); err != nil { - this.PanicWebError(err.Error(), http.StatusRequestedRangeNotSatisfiable) - return + panic(CustomWebResult(CODE_WRAPPER_RANGE_NOT_SATISFIABLE, "range header出错")) } sendSize = ra.length code = http.StatusPartialContent diff --git a/rest/router.go b/rest/router.go index 13fdd54..24ac292 100644 --- a/rest/router.go +++ b/rest/router.go @@ -50,35 +50,26 @@ func NewRouter() *Router { func (this *Router) GlobalPanicHandler(writer http.ResponseWriter, request *http.Request, startTime time.Time) { if err := recover(); err != nil { - LOGGER.Error(fmt.Sprintf("全局异常: %v", err)) + LOGGER.Error("错误: %v", err) var webResult *WebResult = nil if value, ok := err.(string); ok { - writer.WriteHeader(http.StatusBadRequest) - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: value} - } else if _, ok := err.(int); ok { - writer.WriteHeader(http.StatusBadRequest) - webResult = ConstWebResult(CODE_WRAPPER_UNKNOWN) + //一个字符串,默认是请求错误。 + webResult = CustomWebResult(CODE_WRAPPER_BAD_REQUEST, value) } else if value, ok := err.(*WebResult); ok { - writer.WriteHeader(http.StatusBadRequest) + //一个WebResult对象 webResult = value - } else if value, ok := err.(WebResult); ok { - writer.WriteHeader(http.StatusBadRequest) - webResult = &value - } else if value, ok := err.(*WebError); ok { - writer.WriteHeader(value.Code) - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: value.Msg} - } else if value, ok := err.(WebError); ok { - writer.WriteHeader((&value).Code) - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: (&value).Msg} } else if value, ok := err.(error); ok { - writer.WriteHeader(http.StatusBadRequest) - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: value.Error()} + //一个普通的错误对象 + webResult = CustomWebResult(CODE_WRAPPER_UNKNOWN, value.Error()) } else { - writer.WriteHeader(http.StatusInternalServerError) - webResult = &WebResult{Code: CODE_WRAPPER_UNKNOWN.Code, Msg: "服务器未知错误"} + //其他不能识别的内容 + webResult = ConstWebResult(CODE_WRAPPER_UNKNOWN) } + //修改http code码 + writer.WriteHeader(FetchHttpStatus(webResult.Code)) + //输出的是json格式 返回的内容申明是json,utf-8 writer.Header().Set("Content-Type", "application/json;charset=UTF-8") @@ -86,13 +77,14 @@ func (this *Router) GlobalPanicHandler(writer http.ResponseWriter, request *http var json = jsoniter.ConfigCompatibleWithStandardLibrary b, _ := json.Marshal(webResult) - //错误情况记录。 - go this.footprintService.Trace(writer, request, time.Now().Sub(startTime), false) - + //写到输出流中 _, err := fmt.Fprintf(writer, string(b)) if err != nil { fmt.Printf("输出结果时出错了\n") } + + //错误情况记录。 + go this.footprintService.Trace(writer, request, time.Now().Sub(startTime), false) } } diff --git a/rest/user_controller.go b/rest/user_controller.go index f9c1f7b..bbcf28d 100644 --- a/rest/user_controller.go +++ b/rest/user_controller.go @@ -48,17 +48,17 @@ func (this *UserController) Login(writer http.ResponseWriter, request *http.Requ if "" == email || "" == password { - return this.Error("请输入邮箱和密码") + this.PanicBadRequest("请输入邮箱和密码") } user := this.userDao.FindByEmail(email) if user == nil { - return this.Error("邮箱或密码错误") + this.PanicBadRequest("邮箱或密码错误") } else { if !MatchBcrypt(password, user.Password) { - return this.Error("邮箱或密码错误") + this.PanicBadRequest("邮箱或密码错误") } } @@ -184,7 +184,7 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque user.SizeLimit = sizeLimit } else { if currentUser.Uuid != uuid { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } } @@ -297,11 +297,11 @@ func (this *UserController) Disable(writer http.ResponseWriter, request *http.Re loginUser := this.checkUser(writer, request) if uuid == loginUser.Uuid { - return this.Error("你不能操作自己的状态。") + this.PanicBadRequest("你不能操作自己的状态。") } if user.Status == USER_STATUS_DISABLED { - return this.Error("用户已经被禁用,操作无效。") + this.PanicBadRequest("用户已经被禁用,操作无效。") } user.Status = USER_STATUS_DISABLED @@ -320,11 +320,11 @@ func (this *UserController) Enable(writer http.ResponseWriter, request *http.Req user := this.userDao.CheckByUuid(uuid) loginUser := this.checkUser(writer, request) if uuid == loginUser.Uuid { - return this.Error("你不能操作自己的状态。") + this.PanicBadRequest("你不能操作自己的状态。") } if user.Status == USER_STATUS_OK { - return this.Error("用户已经是正常状态,操作无效。") + this.PanicBadRequest("用户已经是正常状态,操作无效。") } user.Status = USER_STATUS_OK @@ -341,7 +341,7 @@ func (this *UserController) ChangePassword(writer http.ResponseWriter, request * oldPassword := request.FormValue("oldPassword") newPassword := request.FormValue("newPassword") if oldPassword == "" || newPassword == "" { - return this.Error("旧密码和新密码都不能为空") + this.PanicBadRequest("旧密码和新密码都不能为空") } user := this.checkUser(writer, request) @@ -352,7 +352,7 @@ func (this *UserController) ChangePassword(writer http.ResponseWriter, request * } if !MatchBcrypt(oldPassword, user.Password) { - return this.Error("旧密码不正确!") + this.PanicBadRequest("旧密码不正确!") } user.Password = GetBcrypt(newPassword) @@ -368,16 +368,16 @@ func (this *UserController) ResetPassword(writer http.ResponseWriter, request *h userUuid := request.FormValue("userUuid") password := request.FormValue("password") if userUuid == "" { - return this.Error("用户不能为空") + this.PanicBadRequest("用户不能为空") } if password == "" { - return this.Error("密码不能为空") + this.PanicBadRequest("密码不能为空") } currentUser := this.checkUser(writer, request) if currentUser.Role != USER_ROLE_ADMINISTRATOR { - return this.Error(CODE_WRAPPER_UNAUTHORIZED) + this.PanicUnauthorized("没有权限") } user := this.userDao.CheckByUuid(userUuid) diff --git a/rest/web_error.go b/rest/web_error.go deleted file mode 100644 index 3caf7cc..0000000 --- a/rest/web_error.go +++ /dev/null @@ -1,10 +0,0 @@ -package rest - -type WebError struct { - Code int `json:"code"` - Msg string `json:"msg"` -} - -func (this *WebError) Error() string { - return this.Msg -} diff --git a/rest/web_result.go b/rest/web_result.go index 396929f..94c4198 100644 --- a/rest/web_result.go +++ b/rest/web_result.go @@ -30,6 +30,7 @@ var ( CODE_WRAPPER_USER_DISABLED = &CodeWrapper{Code: "USER_DISABLED", HttpStatus: http.StatusForbidden, Description: "账户被禁用,禁止访问"} CODE_WRAPPER_UNAUTHORIZED = &CodeWrapper{Code: "LOGIN", HttpStatus: http.StatusUnauthorized, Description: "没有权限,禁止访问"} CODE_WRAPPER_NOT_FOUND = &CodeWrapper{Code: "NOT_FOUND", HttpStatus: http.StatusNotFound, Description: "内容不存在"} + CODE_WRAPPER_RANGE_NOT_SATISFIABLE = &CodeWrapper{Code: "RANGE_NOT_SATISFIABLE", HttpStatus: http.StatusRequestedRangeNotSatisfiable, Description: "文件范围读取错误"} CODE_WRAPPER_UNKNOWN = &CodeWrapper{Code: "UNKNOWN", HttpStatus: http.StatusInternalServerError, Description: "服务器未知错误"} ) @@ -57,6 +58,8 @@ func FetchHttpStatus(code string) int { return CODE_WRAPPER_UNAUTHORIZED.HttpStatus } else if code == CODE_WRAPPER_NOT_FOUND.Code { return CODE_WRAPPER_NOT_FOUND.HttpStatus + } else if code == CODE_WRAPPER_RANGE_NOT_SATISFIABLE.Code { + return CODE_WRAPPER_RANGE_NOT_SATISFIABLE.HttpStatus } else { return CODE_WRAPPER_UNKNOWN.HttpStatus }