diff --git a/error.go b/error.go new file mode 100644 index 0000000..3f0a0a8 --- /dev/null +++ b/error.go @@ -0,0 +1,19 @@ +// Copyright 2023 ecodeclub +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ginx + +import "github.com/ecodeclub/ginx/internal/errs" + +var ErrNoResponse = errs.ErrNoResponse diff --git a/internal/errs/error.go b/internal/errs/error.go index ccd9085..d89da3d 100644 --- a/internal/errs/error.go +++ b/internal/errs/error.go @@ -18,3 +18,8 @@ import "errors" var ErrUnauthorized = errors.New("未授权") var ErrSessionKeyNotFound = errors.New("session 中没找到对应的 key") + +// ErrNoResponse 是一个 sentinel 错误。 +// 也就是说,你可以通过返回这个 ErrNoResponse 来告诉 ginx 不需要继续写响应。 +// 大多数情况下,这意味着你已经写回了响应。 +var ErrNoResponse = errors.New("不需要返回 response") diff --git a/wrapper_func.go b/wrapper_func.go index 54e135f..081060c 100644 --- a/wrapper_func.go +++ b/wrapper_func.go @@ -27,6 +27,10 @@ import ( func W(fn func(ctx *Context) (Result, error)) gin.HandlerFunc { return func(ctx *gin.Context) { res, err := fn(&Context{Context: ctx}) + if errors.Is(err, ErrNoResponse) { + slog.Debug("不需要响应", slog.Any("err", err)) + return + } if errors.Is(err, errs.ErrUnauthorized) { slog.Debug("未授权", slog.Any("err", err)) ctx.AbortWithStatus(http.StatusUnauthorized) @@ -49,6 +53,10 @@ func B[Req any](fn func(ctx *Context, req Req) (Result, error)) gin.HandlerFunc return } res, err := fn(&Context{Context: ctx}, req) + if errors.Is(err, ErrNoResponse) { + slog.Debug("不需要响应", slog.Any("err", err)) + return + } if errors.Is(err, errs.ErrUnauthorized) { slog.Debug("未授权", slog.Any("err", err)) ctx.AbortWithStatus(http.StatusUnauthorized) @@ -80,6 +88,10 @@ func BS[Req any](fn func(ctx *Context, req Req, sess session.Session) (Result, e return } res, err := fn(gtx, req, sess) + if errors.Is(err, ErrNoResponse) { + slog.Debug("不需要响应", slog.Any("err", err)) + return + } // 如果里面有权限校验,那么会返回 401 错误(目前来看,主要是登录态校验) if errors.Is(err, errs.ErrUnauthorized) { slog.Debug("未授权", slog.Any("err", err)) @@ -106,6 +118,10 @@ func S(fn func(ctx *Context, sess session.Session) (Result, error)) gin.HandlerF return } res, err := fn(gtx, sess) + if errors.Is(err, ErrNoResponse) { + slog.Debug("不需要响应", slog.Any("err", err)) + return + } // 如果里面有权限校验,那么会返回 401 错误(目前来看,主要是登录态校验) if errors.Is(err, errs.ErrUnauthorized) { slog.Debug("未授权", slog.Any("err", err))