Files
2025-03-30 16:09:17 +02:00

59 lines
1.4 KiB
Go

package presenter
import (
"context"
"errors"
"fmt"
"log/slog"
"github.com/99designs/gqlgen/graphql"
"github.com/vektah/gqlparser/v2/gqlerror"
)
func New[C ~string, E ~string](logger *slog.Logger, codes []C, entities []E, internalErrorCode C) func(ctx context.Context, e error) *gqlerror.Error {
return func(ctx context.Context, e error) *gqlerror.Error {
err := graphql.DefaultErrorPresenter(ctx, e)
var codedError CodedError
if errors.As(e, &codedError) {
code := toModelErrorCode(codedError.Code, codes, internalErrorCode)
errorEntity := toModelErrorEntity(codedError.Entity, entities)
extensions := map[string]interface{}{"code": code}
if len(errorEntity) > 0 {
extensions["errorEntity"] = errorEntity
}
if len(codedError.Params) > 0 {
extensions["params"] = codedError.Params
}
err.Extensions = extensions
} else {
err.Extensions = map[string]interface{}{"code": internalErrorCode}
}
if logError(e) {
logger.ErrorContext(ctx, fmt.Sprintf("%v", e))
}
return err
}
}
func logError(err error) bool {
return !errors.Is(err, context.Canceled)
}
func toModelErrorCode[C ~string](code Code, codes []C, internalErrorCode C) C {
for _, c := range codes {
if string(c) == string(code) {
return c
}
}
return internalErrorCode
}
func toModelErrorEntity[E ~string](entity Entity, entities []E) E {
for _, e := range entities {
if string(e) == string(entity) {
return e
}
}
return ""
}