Skip to content

Commit 3512bfa

Browse files
committed
fix failing test with missed error handling.
Also bumped the version of the golangci-lint tool
1 parent 1d28871 commit 3512bfa

File tree

5 files changed

+136
-3
lines changed

5 files changed

+136
-3
lines changed

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: golangci-lint
2525
uses: golangci/golangci-lint-action@v8
2626
with:
27-
version: v2.1
27+
version: v2.7
2828
build:
2929
name: Build
3030
runs-on: ubuntu-latest

requests/validate_request.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,33 @@ func ValidateRequestSchema(input *ValidateRequestSchemaInput) (bool, []*errors.V
7676
// Cache miss or no cache - render and compile
7777
if compiledSchema == nil {
7878
renderCtx := base.NewInlineRenderContext()
79-
renderedSchema, _ = input.Schema.RenderInlineWithContext(renderCtx)
79+
var renderErr error
80+
renderedSchema, renderErr = input.Schema.RenderInlineWithContext(renderCtx)
8081
referenceSchema = string(renderedSchema)
82+
83+
// If rendering failed (e.g., circular reference), return the render error
84+
if renderErr != nil {
85+
violation := &errors.SchemaValidationFailure{
86+
Reason: renderErr.Error(),
87+
Location: "schema rendering",
88+
ReferenceSchema: referenceSchema,
89+
}
90+
validationErrors = append(validationErrors, &errors.ValidationError{
91+
ValidationType: helpers.RequestBodyValidation,
92+
ValidationSubType: helpers.Schema,
93+
Message: fmt.Sprintf("%s request body for '%s' failed schema rendering",
94+
input.Request.Method, input.Request.URL.Path),
95+
Reason: fmt.Sprintf("The request schema failed to render: %s",
96+
renderErr.Error()),
97+
SpecLine: 1,
98+
SpecCol: 0,
99+
SchemaValidationErrors: []*errors.SchemaValidationFailure{violation},
100+
HowToFix: "check the request schema for circular references or invalid structures",
101+
Context: referenceSchema,
102+
})
103+
return false, validationErrors
104+
}
105+
81106
jsonSchema, _ = utils.ConvertYAMLtoJSON(renderedSchema)
82107

83108
var err error

requests/validate_request_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,44 @@ func indentLines(s string, indent string) string {
234234
}
235235
return strings.Join(lines, "\n")
236236
}
237+
238+
func TestValidateRequestSchema_CircularReference(t *testing.T) {
239+
// Test when schema has a circular reference that causes render failure
240+
spec := `openapi: 3.1.0
241+
info:
242+
title: Test
243+
version: 1.0.0
244+
components:
245+
schemas:
246+
Error:
247+
type: object
248+
properties:
249+
code:
250+
type: string
251+
details:
252+
type: array
253+
items:
254+
$ref: '#/components/schemas/Error'`
255+
256+
doc, err := libopenapi.NewDocument([]byte(spec))
257+
require.NoError(t, err)
258+
model, errs := doc.BuildV3Model()
259+
require.Empty(t, errs)
260+
261+
// Verify circular reference was detected
262+
require.Len(t, model.Index.GetCircularReferences(), 1)
263+
264+
schema := model.Model.Components.Schemas.GetOrZero("Error")
265+
require.NotNil(t, schema)
266+
267+
valid, errors := ValidateRequestSchema(&ValidateRequestSchemaInput{
268+
Request: postRequestWithBody(`{"code": "abc", "details": [{"code": "def"}]}`),
269+
Schema: schema.Schema(),
270+
Version: 3.1,
271+
})
272+
273+
assert.False(t, valid)
274+
require.Len(t, errors, 1)
275+
assert.Contains(t, errors[0].Message, "failed schema rendering")
276+
assert.Contains(t, errors[0].Reason, "circular reference")
277+
}

responses/validate_response.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,33 @@ func ValidateResponseSchema(input *ValidateResponseSchemaInput) (bool, []*errors
7979
// Cache miss or no cache - render and compile
8080
if compiledSchema == nil {
8181
renderCtx := base.NewInlineRenderContext()
82-
renderedSchema, _ = input.Schema.RenderInlineWithContext(renderCtx)
82+
var renderErr error
83+
renderedSchema, renderErr = input.Schema.RenderInlineWithContext(renderCtx)
8384
referenceSchema = string(renderedSchema)
85+
86+
// If rendering failed (e.g., circular reference), return the render error
87+
if renderErr != nil {
88+
violation := &errors.SchemaValidationFailure{
89+
Reason: renderErr.Error(),
90+
Location: "schema rendering",
91+
ReferenceSchema: referenceSchema,
92+
}
93+
validationErrors = append(validationErrors, &errors.ValidationError{
94+
ValidationType: helpers.ResponseBodyValidation,
95+
ValidationSubType: helpers.Schema,
96+
Message: fmt.Sprintf("%d response body for '%s' failed schema rendering",
97+
input.Response.StatusCode, input.Request.URL.Path),
98+
Reason: fmt.Sprintf("The response schema for status code '%d' failed to render: %s",
99+
input.Response.StatusCode, renderErr.Error()),
100+
SpecLine: 1,
101+
SpecCol: 0,
102+
SchemaValidationErrors: []*errors.SchemaValidationFailure{violation},
103+
HowToFix: "check the response schema for circular references or invalid structures",
104+
Context: referenceSchema,
105+
})
106+
return false, validationErrors
107+
}
108+
84109
jsonSchema, _ = utils.ConvertYAMLtoJSON(renderedSchema)
85110

86111
var err error

responses/validate_response_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,45 @@ func TestValidateResponseSchema_NilSchemaGoLow(t *testing.T) {
249249
assert.Equal(t, "schema cannot be rendered", errors[0].Message)
250250
assert.Contains(t, errors[0].Reason, "does not have low-level information")
251251
}
252+
253+
func TestValidateResponseSchema_CircularReference(t *testing.T) {
254+
// Test when schema has a circular reference that causes render failure
255+
spec := `openapi: 3.1.0
256+
info:
257+
title: Test
258+
version: 1.0.0
259+
components:
260+
schemas:
261+
Error:
262+
type: object
263+
properties:
264+
code:
265+
type: string
266+
details:
267+
type: array
268+
items:
269+
$ref: '#/components/schemas/Error'`
270+
271+
doc, err := libopenapi.NewDocument([]byte(spec))
272+
require.NoError(t, err)
273+
model, errs := doc.BuildV3Model()
274+
require.Empty(t, errs)
275+
276+
// Verify circular reference was detected
277+
require.Len(t, model.Index.GetCircularReferences(), 1)
278+
279+
schema := model.Model.Components.Schemas.GetOrZero("Error")
280+
require.NotNil(t, schema)
281+
282+
valid, errors := ValidateResponseSchema(&ValidateResponseSchemaInput{
283+
Request: postRequest(),
284+
Response: responseWithBody(`{"code": "abc", "details": [{"code": "def"}]}`),
285+
Schema: schema.Schema(),
286+
Version: 3.1,
287+
})
288+
289+
assert.False(t, valid)
290+
require.Len(t, errors, 1)
291+
assert.Contains(t, errors[0].Message, "failed schema rendering")
292+
assert.Contains(t, errors[0].Reason, "circular reference")
293+
}

0 commit comments

Comments
 (0)