diff --git a/router/handler.go b/router/handler.go index dd98bb9..e842e48 100644 --- a/router/handler.go +++ b/router/handler.go @@ -58,34 +58,93 @@ func (s *server) getFormInitValue(ctx *gin.Context, uriCfg UriConfig) (any, erro return formValue, nil } +func (s *server) initRequest(ctx *gin.Context, uriCfg UriConfig) (any, reflect.Value, exception.IException) { + var ( + err error + formValue any + inputValue reflect.Value + ) + if formValue, err = s.getFormInitValue(ctx, uriCfg); nil != err { + return nil, inputValue, exception.NewFromError(http.StatusBadRequest, err) + } + // 表单数据 + inputValue = reflect.ValueOf(formValue) + if !uriCfg.ParamIsPtr { + inputValue = inputValue.Elem() + } + + // 注入公共参数 + if err = s.injectCommonParam(ctx, inputValue); nil != err { + return nil, inputValue, exception.NewFromError(500, err) + } + + // 默认请求失败 + ctx.Set(consts.GinRequestSuccess, false) + // 初始化响应之后 logic + logicAfterResponse := &define.LogicAfterResponse{ + SuccessHookFuncList: make([]func(ctx *gin.Context), 0), + FailureHookFuncList: make([]func(ctx *gin.Context), 0), + Lock: &sync.RWMutex{}, + } + // 此处暴露出去,是为了使用方可以获取到对应数据 + ctx.Set(consts.GinLogicAfterResponseKey, logicAfterResponse) + return formValue, inputValue, nil +} + +// callFunc 调用方法 +func (s *server) callFunc(ctx *gin.Context, uriCfg UriConfig, inputValue reflect.Value) (any, exception.IException) { + + var ( + firstParam = reflect.ValueOf(ctx) + ) + resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, firstParam, inputValue}) + if resList[1].IsNil() { + // 请求成功, 更新标识 + ctx.Set(consts.GinRequestSuccess, true) + return resList[0].Interface(), nil + } + + return nil, s.formatError(ctx, resList[1].Interface()) +} + +// formatError 格式化错误 +func (s *server) formatError(ctx *gin.Context, err any) exception.IException { + if nil == err { + return nil + } + var ( + ok bool + e exception.IException + innerErr error + ) + + // 请求失败 + if ok = errors.As(err.(error), &e); ok { + // 本身就是exception.IException + logger.Instance.Debug("请求结果err类型为 exception.IException, 无需特殊处理", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) + } else if innerErr, ok = err.(error); ok { + logger.Instance.Debug("请求结果err类型为 error, 包装为 exception.IException", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) + e = exception.NewFromError(-1, innerErr) + } else { + logger.Instance.Debug("请求结果err类型 既不是 error 也不是 exception.IException, 包装为 exception.IException", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) + e = exception.NewWithCodeAndData(-1, map[string]any{ + "err": err, + }) + } + return e +} + // RequestHandler 获取请求处理方法 func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc { return func(ctx *gin.Context) { var ( - err error - ok bool - e exception.IException - formValue any - firstParam reflect.Value + err error + e exception.IException + handleResult any + inputValue reflect.Value ) - if formValue, err = s.getFormInitValue(ctx, uriCfg); nil != err { - e = exception.NewFromError(http.StatusBadRequest, err) - response.SendWithException(ctx, e, &define.ResponseOption{ - ContentType: consts.MimeTypeJson, - }) - ctx.Abort() - return - } - // 表单数据 - inputValue := reflect.ValueOf(formValue) - if !uriCfg.ParamIsPtr { - inputValue = inputValue.Elem() - } - - // 注入公共参数 - if err = s.injectCommonParam(ctx, inputValue); nil != err { - e = exception.NewFromError(500, err) + if _, inputValue, e = s.initRequest(ctx, uriCfg); nil != err { response.SendWithException(ctx, e, &define.ResponseOption{ ContentType: consts.MimeTypeJson, }) @@ -93,39 +152,12 @@ func (s *server) RequestHandler(uriCfg UriConfig) gin.HandlerFunc { return } - // 默认请求失败 - ctx.Set(consts.GinRequestSuccess, false) - // 初始化响应之后 logic - logicAfterResponse := &define.LogicAfterResponse{ - SuccessHookFuncList: make([]func(ctx *gin.Context), 0), - FailureHookFuncList: make([]func(ctx *gin.Context), 0), - Lock: &sync.RWMutex{}, - } - // 此处暴露出去,是为了使用方可以获取到对应数据 - ctx.Set(consts.GinLogicAfterResponseKey, logicAfterResponse) defer s.hook(ctx, uriCfg) // 执行 Logic 之后的相关逻辑 - - firstParam = reflect.ValueOf(ctx) - resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, firstParam, inputValue}) - if resList[1].IsNil() { - // 请求成功, 更新标识 - ctx.Set(consts.GinRequestSuccess, true) - response.SuccessWithExtension(ctx, resList[0].Interface(), &define.ResponseOption{ContentType: consts.MimeTypeJson}) + if handleResult, e = s.callFunc(ctx, uriCfg, inputValue); nil != e { + response.SuccessWithExtension(ctx, handleResult, &define.ResponseOption{ContentType: consts.MimeTypeJson}) return } - // 请求失败 - if ok = errors.As(resList[1].Interface().(error), &e); ok { - // 本身就是exception.IException - logger.Instance.Debug("请求结果err类型为 exception.IException, 无需特殊处理", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) - } else if err, ok = resList[1].Interface().(error); ok { - logger.Instance.Debug("请求结果err类型为 error, 包装为 exception.IException", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) - e = exception.NewFromError(-1, err) - } else { - logger.Instance.Debug("请求结果err类型 既不是 error 也不是 exception.IException, 包装为 exception.IException", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) - e = exception.NewWithCodeAndData(-1, map[string]any{ - "err": resList[1].Interface(), - }) - } + response.SendWithException(ctx, e, &define.ResponseOption{ ContentType: consts.MimeTypeJson, }) @@ -137,13 +169,12 @@ func (s *server) SseHandler(uriCfg UriConfig) gin.HandlerFunc { return func(ctx *gin.Context) { var ( err error - ok bool e exception.IException - formValue any + inputValue reflect.Value firstParam reflect.Value ) - if formValue, err = s.getFormInitValue(ctx, uriCfg); nil != err { + if _, inputValue, err = s.initRequest(ctx, uriCfg); nil != err { e = exception.NewFromError(http.StatusBadRequest, err) response.SendWithException(ctx, e, &define.ResponseOption{ ContentType: consts.MimeTypeJson, @@ -151,28 +182,6 @@ func (s *server) SseHandler(uriCfg UriConfig) gin.HandlerFunc { ctx.Abort() return } - // 表单数据 - inputValue := reflect.ValueOf(formValue).Elem() - - // 注入公共参数 - if err = s.injectCommonParam(ctx, inputValue); nil != err { - e = exception.NewFromError(500, err) - response.SendWithException(ctx, e, &define.ResponseOption{ - ContentType: consts.MimeTypeJson, - }) - ctx.Abort() - return - } - - ctx.Set(consts.GinRequestSuccess, false) - // 初始化响应之后 logic - logicAfterResponse := &define.LogicAfterResponse{ - SuccessHookFuncList: make([]func(ctx *gin.Context), 0), - FailureHookFuncList: make([]func(ctx *gin.Context), 0), - Lock: &sync.RWMutex{}, - } - // 此处暴露出去,是为了使用方可以获取到对应数据 - ctx.Set(consts.GinLogicAfterResponseKey, logicAfterResponse) defer s.hook(ctx, uriCfg) // 执行 Logic 之后的相关逻辑 ctx.Writer.Header().Set(consts.HeaderKeyContentType.String(), "text/event-stream") @@ -221,18 +230,7 @@ func (s *server) SseHandler(uriCfg UriConfig) gin.HandlerFunc { return } // 请求失败 - if ok = errors.As(resList[1].Interface().(error), &e); ok { - // 本身就是exception.IException - logger.Instance.Debug("请求结果err类型为 exception.IException, 无需特殊处理", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) - } else if err, ok = resList[1].Interface().(error); ok { - logger.Instance.Debug("请求结果err类型为 error, 包装为 exception.IException", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) - e = exception.NewFromError(-1, err) - } else { - logger.Instance.Debug("请求结果err类型 既不是 error 也不是 exception.IException, 包装为 exception.IException", loggerPkg.NewLogData(util.GinCtxToContext(ctx), logger.RecordType, logger.CodeLogicErrorWrapper, map[string]any{}).ToFieldList()...) - e = exception.NewWithCodeAndData(-1, map[string]any{ - "err": resList[1].Interface(), - }) - } + e = s.formatError(ctx, resList[1].Interface()) if nil != e { // 异常终止 if _, err = fmt.Fprintf(ctx.Writer, define.SseMsgFormat, -3, "system", serialize.JSON.MarshalForStringIgnoreError(define.SseData{