[#191] Refactor error handling and logging
Some checks failed
/ DCO (pull_request) Successful in 36s
/ Builds (pull_request) Successful in 1m3s
/ Vulncheck (pull_request) Successful in 58s
/ OCI image (pull_request) Successful in 1m17s
/ Lint (pull_request) Failing after 1m26s
/ Tests (pull_request) Successful in 1m4s
/ Integration tests (pull_request) Failing after 5m32s

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
Denis Kirillov 2025-03-03 18:06:41 +03:00
parent 9cf2a4f0e0
commit 982ae32bc4
15 changed files with 251 additions and 316 deletions

View file

@ -7,11 +7,11 @@ import (
"strings"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/layer"
"git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-http-gw/tokens"
"git.frostfs.info/TrueCloudLab/frostfs-http-gw/utils"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
sdkstatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
@ -31,15 +31,10 @@ func newRequest(ctx *fasthttp.RequestCtx, log *zap.Logger) request {
}
}
func (r *request) handleFrostFSErr(err error, start time.Time) {
logFields := []zap.Field{
zap.Stringer("elapsed", time.Since(start)),
zap.Error(err),
}
statusCode, msg, additionalFields := formErrorResponse("could not receive object", err)
logFields = append(logFields, additionalFields...)
r.log.Error(logs.CouldNotReceiveObject, append(logFields, logs.TagField(logs.TagExternalStorage))...)
func (r *request) logAndSendError(err error, start time.Time) {
msg, statusCode := formErrorResponse(err)
r.log.Error(logs.CouldNotReceiveObject, zap.Stringer("elapsed", time.Since(start)),
zap.Error(err), logs.TagField(logs.TagExternalStorage))
ResponseError(r.RequestCtx, msg, statusCode)
}
@ -84,14 +79,23 @@ func isValidValue(s string) bool {
return true
}
func logAndSendBucketError(c *fasthttp.RequestCtx, log *zap.Logger, err error) {
log.Error(logs.CouldNotGetBucket, zap.Error(err), logs.TagField(logs.TagDatapath))
func (h *Handler) reqLogger(ctx context.Context) *zap.Logger {
return utils.GetReqLogOrDefault(ctx, h.log)
}
if client.IsErrContainerNotFound(err) {
ResponseError(c, "Not Found", fasthttp.StatusNotFound)
return
}
ResponseError(c, "could not get bucket: "+err.Error(), fasthttp.StatusBadRequest)
func (h *Handler) logAndSendError(ctx context.Context, c *fasthttp.RequestCtx, msg string, err error, additional ...zap.Field) {
utils.GetReqLogOrDefault(ctx, h.log).Error(msg,
append([]zap.Field{zap.Error(err), logs.TagField(logs.TagDatapath)}, additional...)...)
msg, code := formErrorResponse(err)
ResponseError(c, msg, code)
}
func logAndSendBucketError(c *fasthttp.RequestCtx, msgLog string, log *zap.Logger, err error) {
log.Error(msgLog, zap.Error(err), logs.TagField(logs.TagDatapath))
msg, code := formErrorResponse(err)
ResponseError(c, msg, code)
}
func newAddress(cnr cid.ID, obj oid.ID) oid.Address {
@ -112,31 +116,23 @@ func ResponseError(r *fasthttp.RequestCtx, msg string, code int) {
r.Error(msg+"\n", code)
}
func formErrorResponse(message string, err error) (int, string, []zap.Field) {
var (
msg string
statusCode int
logFields []zap.Field
)
st := new(sdkstatus.ObjectAccessDenied)
func formErrorResponse(err error) (string, int) {
switch {
case errors.As(err, &st):
statusCode = fasthttp.StatusForbidden
reason := st.Reason()
msg = fmt.Sprintf("%s: %v: %s", message, err, reason)
logFields = append(logFields, zap.String("error_detail", reason))
case errors.Is(err, ErrAccessDenied):
return fmt.Sprintf("Storage Access Denied:\n%v", err), fasthttp.StatusForbidden
case errors.Is(err, layer.ErrNodeAccessDenied):
return fmt.Sprintf("Tree Access Denied:\n%v", err), fasthttp.StatusForbidden
case errors.Is(err, ErrQuotaLimitReached):
statusCode = fasthttp.StatusConflict
msg = fmt.Sprintf("%s: %v", message, err)
case client.IsErrObjectNotFound(err) || client.IsErrContainerNotFound(err):
statusCode = fasthttp.StatusNotFound
msg = "Not Found"
return fmt.Sprintf("Quota Reached:\n%v", err), fasthttp.StatusConflict
case errors.Is(err, ErrContainerNotFound):
return fmt.Sprintf("Container Not Found:\n%v", err), fasthttp.StatusNotFound
case errors.Is(err, ErrObjectNotFound):
return fmt.Sprintf("Object Not Found:\n%v", err), fasthttp.StatusNotFound
case errors.Is(err, layer.ErrNodeNotFound):
return fmt.Sprintf("Tree Node Not Found:\n%v", err), fasthttp.StatusNotFound
case errors.Is(err, ErrGatewayTimeout):
return fmt.Sprintf("Gateway Timeout:\n%v", err), fasthttp.StatusGatewayTimeout
default:
statusCode = fasthttp.StatusBadRequest
msg = fmt.Sprintf("%s: %v", message, err)
return fmt.Sprintf("Bad Request:\n%v", err), fasthttp.StatusBadRequest
}
return statusCode, msg, logFields
}