|
@@ -13,40 +13,24 @@ import (
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
- errorHandler func(error) (int, any)
|
|
|
- errorHandlerCtx func(context.Context, error) (int, any)
|
|
|
- commonHandler func(any) any
|
|
|
- commonHandlerCtx func(context.Context, any) any
|
|
|
- lock sync.RWMutex
|
|
|
- cLock sync.RWMutex
|
|
|
+ errorHandler func(context.Context, error) (int, any)
|
|
|
+ errorLock sync.RWMutex
|
|
|
+ respHandler func(context.Context, any) any
|
|
|
+ respLock sync.RWMutex
|
|
|
)
|
|
|
|
|
|
// Error writes err into w.
|
|
|
func Error(w http.ResponseWriter, err error, fns ...func(w http.ResponseWriter, err error)) {
|
|
|
- lock.RLock()
|
|
|
- handler := errorHandler
|
|
|
- lock.RUnlock()
|
|
|
-
|
|
|
- doHandleError(w, err, handler, WriteJson, fns...)
|
|
|
+ doHandleError(w, err, buildErrorHandler(context.Background()), WriteJson, fns...)
|
|
|
}
|
|
|
|
|
|
// ErrorCtx writes err into w.
|
|
|
func ErrorCtx(ctx context.Context, w http.ResponseWriter, err error,
|
|
|
fns ...func(w http.ResponseWriter, err error)) {
|
|
|
- lock.RLock()
|
|
|
- handlerCtx := errorHandlerCtx
|
|
|
- lock.RUnlock()
|
|
|
-
|
|
|
- var handler func(error) (int, any)
|
|
|
- if handlerCtx != nil {
|
|
|
- handler = func(err error) (int, any) {
|
|
|
- return handlerCtx(ctx, err)
|
|
|
- }
|
|
|
- }
|
|
|
writeJson := func(w http.ResponseWriter, code int, v any) {
|
|
|
WriteJsonCtx(ctx, w, code, v)
|
|
|
}
|
|
|
- doHandleError(w, err, handler, writeJson, fns...)
|
|
|
+ doHandleError(w, err, buildErrorHandler(ctx), writeJson, fns...)
|
|
|
}
|
|
|
|
|
|
// Ok writes HTTP 200 OK into w.
|
|
@@ -56,20 +40,20 @@ func Ok(w http.ResponseWriter) {
|
|
|
|
|
|
// OkJson writes v into w with 200 OK.
|
|
|
func OkJson(w http.ResponseWriter, v any) {
|
|
|
- cLock.RLock()
|
|
|
- handler := commonHandler
|
|
|
- cLock.RUnlock()
|
|
|
+ respLock.RLock()
|
|
|
+ handler := respHandler
|
|
|
+ respLock.RUnlock()
|
|
|
if handler != nil {
|
|
|
- v = handler(v)
|
|
|
+ v = handler(context.Background(), v)
|
|
|
}
|
|
|
WriteJson(w, http.StatusOK, v)
|
|
|
}
|
|
|
|
|
|
// OkJsonCtx writes v into w with 200 OK.
|
|
|
func OkJsonCtx(ctx context.Context, w http.ResponseWriter, v any) {
|
|
|
- cLock.RLock()
|
|
|
- handlerCtx := commonHandlerCtx
|
|
|
- cLock.RUnlock()
|
|
|
+ respLock.RLock()
|
|
|
+ handlerCtx := respHandler
|
|
|
+ respLock.RUnlock()
|
|
|
if handlerCtx != nil {
|
|
|
v = handlerCtx(ctx, v)
|
|
|
}
|
|
@@ -77,31 +61,30 @@ func OkJsonCtx(ctx context.Context, w http.ResponseWriter, v any) {
|
|
|
}
|
|
|
|
|
|
// SetErrorHandler sets the error handler, which is called on calling Error.
|
|
|
+// Notice: SetErrorHandler and SetErrorHandlerCtx set the same error handler.
|
|
|
+// Keeping both SetErrorHandler and SetErrorHandlerCtx is for backward compatibility.
|
|
|
func SetErrorHandler(handler func(error) (int, any)) {
|
|
|
- lock.Lock()
|
|
|
- defer lock.Unlock()
|
|
|
- errorHandler = handler
|
|
|
+ errorLock.Lock()
|
|
|
+ defer errorLock.Unlock()
|
|
|
+ errorHandler = func(_ context.Context, err error) (int, any) {
|
|
|
+ return handler(err)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// SetErrorHandlerCtx sets the error handler, which is called on calling Error.
|
|
|
+// Notice: SetErrorHandler and SetErrorHandlerCtx set the same error handler.
|
|
|
+// Keeping both SetErrorHandler and SetErrorHandlerCtx is for backward compatibility.
|
|
|
func SetErrorHandlerCtx(handlerCtx func(context.Context, error) (int, any)) {
|
|
|
- lock.Lock()
|
|
|
- defer lock.Unlock()
|
|
|
- errorHandlerCtx = handlerCtx
|
|
|
-}
|
|
|
-
|
|
|
-// SetCommonHandler sets the common handler, which is called on calling OkJson.
|
|
|
-func SetCommonHandler(handler func(any) any) {
|
|
|
- cLock.Lock()
|
|
|
- defer cLock.Unlock()
|
|
|
- commonHandler = handler
|
|
|
+ errorLock.Lock()
|
|
|
+ defer errorLock.Unlock()
|
|
|
+ errorHandler = handlerCtx
|
|
|
}
|
|
|
|
|
|
-// SetCommonHandlerCtx sets the common handler, which is called on calling OkJson.
|
|
|
-func SetCommonHandlerCtx(handlerCtx func(context.Context, any) any) {
|
|
|
- cLock.Lock()
|
|
|
- defer cLock.Unlock()
|
|
|
- commonHandlerCtx = handlerCtx
|
|
|
+// SetResponseHandler sets the response handler, which is called on calling OkJson and OkJsonCtx.
|
|
|
+func SetResponseHandler(handler func(context.Context, any) any) {
|
|
|
+ respLock.Lock()
|
|
|
+ defer respLock.Unlock()
|
|
|
+ respHandler = handler
|
|
|
}
|
|
|
|
|
|
// WriteJson writes v as json string into w with code.
|
|
@@ -118,6 +101,21 @@ func WriteJsonCtx(ctx context.Context, w http.ResponseWriter, code int, v any) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func buildErrorHandler(ctx context.Context) func(error) (int, any) {
|
|
|
+ errorLock.RLock()
|
|
|
+ handlerCtx := errorHandler
|
|
|
+ errorLock.RUnlock()
|
|
|
+
|
|
|
+ var handler func(error) (int, any)
|
|
|
+ if handlerCtx != nil {
|
|
|
+ handler = func(err error) (int, any) {
|
|
|
+ return handlerCtx(ctx, err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return handler
|
|
|
+}
|
|
|
+
|
|
|
func doHandleError(w http.ResponseWriter, err error, handler func(error) (int, any),
|
|
|
writeJson func(w http.ResponseWriter, code int, v any),
|
|
|
fns ...func(w http.ResponseWriter, err error)) {
|