[#18] Extract error details #19

Merged
alexvanin merged 1 commit from dkirillov/frostfs-http-gw:feature/18-exctract_error_details into master 2023-03-14 16:21:22 +00:00
4 changed files with 50 additions and 12 deletions

View file

@ -11,6 +11,7 @@ This document outlines major changes between releases.
- Update go version to 1.18 (TrueCloudLab#9) - Update go version to 1.18 (TrueCloudLab#9)
- Update neo-go to v0.101.0 (#8) - Update neo-go to v0.101.0 (#8)
- Update viper to v1.15.0 (#8) - Update viper to v1.15.0 (#8)
- Errors have become more detailed (#18)
## [0.26.0] - 2022-12-28 ## [0.26.0] - 2022-12-28

View file

@ -225,19 +225,15 @@ func bearerToken(ctx context.Context) *bearer.Token {
} }
func (r *request) handleFrostFSErr(err error, start time.Time) { func (r *request) handleFrostFSErr(err error, start time.Time) {
r.log.Error( logFields := []zap.Field{
"could not receive object",
zap.Stringer("elapsed", time.Since(start)), zap.Stringer("elapsed", time.Since(start)),
zap.Error(err), zap.Error(err),
)
if client.IsErrObjectNotFound(err) || client.IsErrContainerNotFound(err) {
response.Error(r.RequestCtx, "Not Found", fasthttp.StatusNotFound)
return
} }
statusCode, msg, additionalFields := response.FormErrorResponse("could not receive object", err)
logFields = append(logFields, additionalFields...)
msg := fmt.Sprintf("could not receive object: %v", err) r.log.Error("could not receive object", logFields...)
response.Error(r.RequestCtx, msg, fasthttp.StatusBadRequest) response.Error(r.RequestCtx, msg, statusCode)
} }
// Downloader is a download request handler. // Downloader is a download request handler.

View file

@ -1,7 +1,41 @@
package response package response
import "github.com/valyala/fasthttp" import (
"errors"
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
sdkstatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
"github.com/valyala/fasthttp"
"go.uber.org/zap"
)
func Error(r *fasthttp.RequestCtx, msg string, code int) { func Error(r *fasthttp.RequestCtx, msg string, code int) {
r.Error(msg+"\n", code) 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)
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 client.IsErrObjectNotFound(err) || client.IsErrContainerNotFound(err):
statusCode = fasthttp.StatusNotFound
msg = "NotFound"
default:
statusCode = fasthttp.StatusBadRequest
msg = fmt.Sprintf("%s: %v", message, err)
}
return statusCode, msg, logFields
}

View file

@ -182,8 +182,7 @@ func (u *Uploader) Upload(c *fasthttp.RequestCtx) {
} }
if idObj, err = u.pool.PutObject(u.appCtx, prm); err != nil { if idObj, err = u.pool.PutObject(u.appCtx, prm); err != nil {
log.Error("could not store file in frostfs", zap.Error(err)) u.handlePutFrostFSErr(c, err)
response.Error(c, "could not store file in frostfs: "+err.Error(), fasthttp.StatusBadRequest)
return return
} }
@ -214,6 +213,14 @@ func (u *Uploader) Upload(c *fasthttp.RequestCtx) {
c.Response.Header.SetContentType(jsonHeader) c.Response.Header.SetContentType(jsonHeader)
} }
func (u *Uploader) handlePutFrostFSErr(r *fasthttp.RequestCtx, err error) {
statusCode, msg, additionalFields := response.FormErrorResponse("could not store file in frostfs", err)
logFields := append([]zap.Field{zap.Error(err)}, additionalFields...)
u.log.Error("could not store file in frostfs", logFields...)
response.Error(r, msg, statusCode)
}
func (u *Uploader) fetchOwnerAndBearerToken(ctx context.Context) (*user.ID, *bearer.Token) { func (u *Uploader) fetchOwnerAndBearerToken(ctx context.Context) (*user.ID, *bearer.Token) {
if tkn, err := tokens.LoadBearerToken(ctx); err == nil && tkn != nil { if tkn, err := tokens.LoadBearerToken(ctx); err == nil && tkn != nil {
issuer := bearer.ResolveIssuer(*tkn) issuer := bearer.ResolveIssuer(*tkn)