Skip to content

Commit 36e954c

Browse files
committed
Add allow_all_extension_fields configuration
1 parent 29c746e commit 36e954c

File tree

7 files changed

+95
-16
lines changed

7 files changed

+95
-16
lines changed

router-tests/error_handling_test.go

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,68 @@ func TestAllowedExtensions(t *testing.T) {
249249
})
250250
})
251251

252-
t.Run("in passthrough mode, all extensions should be included in the propagated error", func(t *testing.T) {
252+
t.Run("in wrapped mode, with AllowAllExtensionFields set, all extensions should be included in the propagated error", func(t *testing.T) {
253+
testenv.Run(t, &testenv.Config{
254+
ModifySubgraphErrorPropagation: func(cfg *config.SubgraphErrorPropagationConfiguration) {
255+
cfg.Enabled = true
256+
cfg.Mode = config.SubgraphErrorPropagationModeWrapped
257+
cfg.AllowedExtensionFields = []string{"allowed"}
258+
cfg.AllowAllExtensionFields = true
259+
},
260+
Subgraphs: testenv.SubgraphsConfig{
261+
Employees: testenv.SubgraphConfig{
262+
Middleware: func(handler http.Handler) http.Handler {
263+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
264+
w.Header().Set("Content-Type", "application/json")
265+
w.WriteHeader(http.StatusForbidden)
266+
_, wErr := w.Write([]byte(`{"errors":[{"message":"Unauthorized","extensions":{"allowed":"allowed","notAllowed":"notAllowed"}}]}`))
267+
require.NoError(t, wErr)
268+
})
269+
},
270+
},
271+
},
272+
}, func(t *testing.T, xEnv *testenv.Environment) {
273+
res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
274+
Query: `{ employees { id } }`,
275+
})
276+
require.Equal(t, `{"errors":[{"message":"Failed to fetch from Subgraph 'employees'.","extensions":{"errors":[{"message":"Unauthorized","extensions":{"allowed":"allowed","notAllowed":"notAllowed"}}],"statusCode":403}}],"data":{"employees":null}}`, res.Body)
277+
})
278+
})
279+
280+
t.Run("in passthrough mode, only allowed extensions should be included in the propagated error", func(t *testing.T) {
281+
testenv.Run(t, &testenv.Config{
282+
ModifySubgraphErrorPropagation: func(cfg *config.SubgraphErrorPropagationConfiguration) {
283+
cfg.Enabled = true
284+
cfg.Mode = config.SubgraphErrorPropagationModePassthrough
285+
cfg.AllowedExtensionFields = []string{"allowed"}
286+
},
287+
Subgraphs: testenv.SubgraphsConfig{
288+
Employees: testenv.SubgraphConfig{
289+
Middleware: func(handler http.Handler) http.Handler {
290+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
291+
w.Header().Set("Content-Type", "application/json")
292+
w.WriteHeader(http.StatusForbidden)
293+
_, wErr := w.Write([]byte(`{"errors":[{"message":"Unauthorized","extensions":{"allowed":"allowed","notAllowed":"notAllowed"}}]}`))
294+
require.NoError(t, wErr)
295+
})
296+
},
297+
},
298+
},
299+
}, func(t *testing.T, xEnv *testenv.Environment) {
300+
res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
301+
Query: `{ employees { id } }`,
302+
})
303+
require.Equal(t, `{"errors":[{"message":"Unauthorized","extensions":{"allowed":"allowed","statusCode":403}}],"data":{"employees":null}}`, res.Body)
304+
})
305+
})
306+
307+
t.Run("in passthrough mode, with AllowAllExtensionFields set, all extensions should be included in the propagated error", func(t *testing.T) {
253308
testenv.Run(t, &testenv.Config{
254309
ModifySubgraphErrorPropagation: func(cfg *config.SubgraphErrorPropagationConfiguration) {
255310
cfg.Enabled = true
256311
cfg.Mode = config.SubgraphErrorPropagationModePassthrough
257312
cfg.AllowedExtensionFields = []string{"allowed"}
313+
cfg.AllowAllExtensionFields = true
258314
},
259315
Subgraphs: testenv.SubgraphsConfig{
260316
Employees: testenv.SubgraphConfig{

router/core/executor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func (b *ExecutorConfigurationBuilder) Build(ctx context.Context, opts *Executor
8181
AttachServiceNameToErrorExtensions: opts.RouterEngineConfig.SubgraphErrorPropagation.AttachServiceName,
8282
DefaultErrorExtensionCode: opts.RouterEngineConfig.SubgraphErrorPropagation.DefaultExtensionCode,
8383
AllowedSubgraphErrorFields: opts.RouterEngineConfig.SubgraphErrorPropagation.AllowedFields,
84+
AllowAllErrorExtensionFields: opts.RouterEngineConfig.SubgraphErrorPropagation.AllowAllExtensionFields,
8485
MaxRecyclableParserSize: opts.RouterEngineConfig.Execution.ResolverMaxRecyclableParserSize,
8586
MultipartSubHeartbeatInterval: opts.HeartbeatInterval,
8687
MaxSubscriptionFetchTimeout: opts.RouterEngineConfig.Execution.SubscriptionFetchTimeout,

router/pkg/config/config.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -724,16 +724,17 @@ const (
724724
)
725725

726726
type SubgraphErrorPropagationConfiguration struct {
727-
Enabled bool `yaml:"enabled" envDefault:"true" env:"SUBGRAPH_ERROR_PROPAGATION_ENABLED"`
728-
PropagateStatusCodes bool `yaml:"propagate_status_codes" envDefault:"false" env:"SUBGRAPH_ERROR_PROPAGATION_STATUS_CODES"`
729-
Mode SubgraphErrorPropagationMode `yaml:"mode" envDefault:"wrapped" env:"SUBGRAPH_ERROR_PROPAGATION_MODE"`
730-
RewritePaths bool `yaml:"rewrite_paths" envDefault:"true" env:"SUBGRAPH_ERROR_PROPAGATION_REWRITE_PATHS"`
731-
OmitLocations bool `yaml:"omit_locations" envDefault:"true" env:"SUBGRAPH_ERROR_PROPAGATION_OMIT_LOCATIONS"`
732-
OmitExtensions bool `yaml:"omit_extensions" envDefault:"false" env:"SUBGRAPH_ERROR_PROPAGATION_OMIT_EXTENSIONS"`
733-
AttachServiceName bool `yaml:"attach_service_name" envDefault:"true" env:"SUBGRAPH_ERROR_PROPAGATION_ATTACH_SERVICE_NAME"`
734-
DefaultExtensionCode string `yaml:"default_extension_code" envDefault:"DOWNSTREAM_SERVICE_ERROR" env:"SUBGRAPH_ERROR_PROPAGATION_DEFAULT_EXTENSION_CODE"`
735-
AllowedExtensionFields []string `yaml:"allowed_extension_fields" envDefault:"code" env:"SUBGRAPH_ERROR_PROPAGATION_ALLOWED_EXTENSION_FIELDS"`
736-
AllowedFields []string `yaml:"allowed_fields" env:"SUBGRAPH_ERROR_PROPAGATION_ALLOWED_FIELDS"`
727+
Enabled bool `yaml:"enabled" envDefault:"true" env:"ENABLED"`
728+
PropagateStatusCodes bool `yaml:"propagate_status_codes" envDefault:"false" env:"STATUS_CODES"`
729+
Mode SubgraphErrorPropagationMode `yaml:"mode" envDefault:"wrapped" env:"MODE"`
730+
RewritePaths bool `yaml:"rewrite_paths" envDefault:"true" env:"REWRITE_PATHS"`
731+
OmitLocations bool `yaml:"omit_locations" envDefault:"true" env:"OMIT_LOCATIONS"`
732+
OmitExtensions bool `yaml:"omit_extensions" envDefault:"false" env:"OMIT_EXTENSIONS"`
733+
AttachServiceName bool `yaml:"attach_service_name" envDefault:"true" env:"ATTACH_SERVICE_NAME"`
734+
DefaultExtensionCode string `yaml:"default_extension_code" envDefault:"DOWNSTREAM_SERVICE_ERROR" env:"DEFAULT_EXTENSION_CODE"`
735+
AllowAllExtensionFields bool `yaml:"allow_all_extension_fields" envDefault:"false" env:"ALLOW_ALL_EXTENSION_FIELDS"`
736+
AllowedExtensionFields []string `yaml:"allowed_extension_fields" envDefault:"code" env:"ALLOWED_EXTENSION_FIELDS"`
737+
AllowedFields []string `yaml:"allowed_fields" env:"ALLOWED_FIELDS"`
737738
}
738739

739740
type StorageProviders struct {
@@ -1009,7 +1010,7 @@ type Config struct {
10091010

10101011
WebSocket WebSocketConfiguration `yaml:"websocket,omitempty"`
10111012

1012-
SubgraphErrorPropagation SubgraphErrorPropagationConfiguration `yaml:"subgraph_error_propagation"`
1013+
SubgraphErrorPropagation SubgraphErrorPropagationConfiguration `yaml:"subgraph_error_propagation" envPrefix:"SUBGRAPH_ERROR_PROPAGATION_"`
10131014

10141015
StorageProviders StorageProviders `yaml:"storage_providers"`
10151016
ExecutionConfig ExecutionConfig `yaml:"execution_config"`

router/pkg/config/config.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,11 @@
27062706
"default": ["code"],
27072707
"description": "The allowed extension fields. The allowed extension fields are used to specify which fields of the Subgraph errors are allowed to be propagated to the client."
27082708
},
2709+
"allow_all_extension_fields": {
2710+
"type": "boolean",
2711+
"default": false,
2712+
"description": "Allow all extension fields from Subgraph errors to be propagated to the client. If the value is true (default: false), all extension fields from Subgraph errors will be propagated, overriding the allowed_extension_fields configuration."
2713+
},
27092714
"omit_locations": {
27102715
"type": "boolean",
27112716
"default": true,

router/pkg/config/fixtures/full.yaml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ events:
314314
redis:
315315
- id: my-redis
316316
urls:
317-
- "redis://localhost:6379/11"
317+
- 'redis://localhost:6379/11'
318318
cluster_enabled: true
319319

320320
engine:
@@ -445,6 +445,19 @@ automatic_persisted_queries:
445445
provider_id: redis
446446
object_prefix: 'cosmo_apq'
447447

448+
subgraph_error_propagation:
449+
mode: pass-through
450+
rewrite_paths: true
451+
attach_service_name: true
452+
default_extension_code: DOWNSTREAM_SERVICE_ERROR
453+
omit_locations: true
454+
omit_extensions: true
455+
propagate_status_codes: false
456+
allowed_extension_fields:
457+
- 'field1'
458+
- 'field2'
459+
allow_all_extension_fields: true
460+
448461
execution_config:
449462
storage:
450463
provider_id: s3

router/pkg/config/testdata/config_defaults.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@
406406
"OmitExtensions": false,
407407
"AttachServiceName": true,
408408
"DefaultExtensionCode": "DOWNSTREAM_SERVICE_ERROR",
409+
"AllowAllExtensionFields": false,
409410
"AllowedExtensionFields": [
410411
"code"
411412
],

router/pkg/config/testdata/config_full.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,14 +747,16 @@
747747
"SubgraphErrorPropagation": {
748748
"Enabled": true,
749749
"PropagateStatusCodes": false,
750-
"Mode": "wrapped",
750+
"Mode": "pass-through",
751751
"RewritePaths": true,
752752
"OmitLocations": true,
753-
"OmitExtensions": false,
753+
"OmitExtensions": true,
754754
"AttachServiceName": true,
755755
"DefaultExtensionCode": "DOWNSTREAM_SERVICE_ERROR",
756+
"AllowAllExtensionFields": true,
756757
"AllowedExtensionFields": [
757-
"code"
758+
"field1",
759+
"field2"
758760
],
759761
"AllowedFields": null
760762
},

0 commit comments

Comments
 (0)