...
1 package apierror
2
3 import (
4 "context"
5 "errors"
6
7 "github.com/99designs/gqlgen/graphql"
8 "github.com/vektah/gqlparser/v2/gqlerror"
9
10 "edge-infra.dev/pkg/lib/fog"
11 "edge-infra.dev/pkg/lib/runtime/version"
12 )
13
14 const (
15
16 StatusCode = "statusCode"
17 )
18
19 type IsAPIError interface {
20 Error() string
21 Extensions() map[string]interface{}
22 }
23
24
25 type Extension struct{}
26
27 func (e Extension) ExtensionName() string { return "APIErrorConverter" }
28 func (e Extension) Validate(_ graphql.ExecutableSchema) error { return nil }
29 func (e Extension) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
30 resp := next(ctx)
31 for i, err := range resp.Errors {
32 if apiError, ok := err.Unwrap().(IsAPIError); ok {
33 resp.Errors[i] = toAPIError(ctx, apiError)
34 }
35 }
36 return resp
37 }
38
39
40 func IsNotFoundError(err error) bool {
41 if e, ok := err.(IsAPIError); ok {
42 return e != nil && e.Extensions()[StatusCode] == 404
43 }
44 return false
45 }
46
47
48 func IsForbiddenError(err error) bool {
49 if e, ok := err.(IsAPIError); ok {
50 return e != nil && e.Extensions()[StatusCode] == 403
51 }
52 return false
53 }
54
55
56 func AddAPIErrorToResponse(ctx context.Context, err error) error {
57 if e, ok := err.(IsAPIError); ok {
58 graphql.AddError(ctx, toAPIError(ctx, e))
59 return nil
60 }
61 return err
62 }
63
64
65 func AddEmptyAPIErrorToResponse(ctx context.Context, err error) error {
66 if e, ok := err.(IsAPIError); ok {
67 graphql.AddError(ctx, toAPIError(ctx, e))
68 return errors.New("")
69 }
70 return err
71 }
72
73 func toAPIError(ctx context.Context, err IsAPIError) *gqlerror.Error {
74 if err != nil {
75 graphqlExt := make(map[string]interface{})
76 if val, exists := graphqlExt[OperationIDKey]; !exists || val.(string) == "" {
77 graphqlExt[OperationIDKey] = fog.OperationID(ctx)
78 }
79 if val, exists := graphqlExt[VersionKey]; !exists || val.(string) == "" {
80 graphqlExt[VersionKey] = version.New().SemVer
81 }
82 graphqlExt[AdditionalKey] = err.Extensions()
83 return &gqlerror.Error{
84 Path: graphql.GetPath(ctx),
85 Message: err.Error(),
86 Extensions: graphqlExt,
87 }
88 }
89 return nil
90 }
91
View as plain text