Skip to content

Make errors consistent#3

Draft
mjbonifacio wants to merge 15 commits intoclarify-error-typesfrom
make-errors-consistent
Draft

Make errors consistent#3
mjbonifacio wants to merge 15 commits intoclarify-error-typesfrom
make-errors-consistent

Conversation

@mjbonifacio
Copy link
Owner

No description provided.

Michael Bonifacio added 15 commits November 5, 2025 17:11
…emove SchemaValidationFailure from when json schema compilation fails
…inlining

AbsoluteKeywordLocation was never populated because libopenapi's RenderInline()
method resolves and inlines all $ref references before schemas reach the JSON
Schema validator. Since the validator never encounters $ref pointers, this field
remained empty in all cases and served no purpose.

Removed from:
- SchemaValidationFailure struct definition
- All instantiation sites (schema_validation, parameters, requests)
- Improved KeywordLocation documentation with JSON Pointer reference
…dation errors, add KeywordLocation to schema violations

Pre-validation errors (compilation, JSON decode, empty body) now correctly
omit SchemaValidationFailure objects, as they don't represent actual schema
constraint violations.

Actual schema violations now include KeywordLocation (JSON Pointer path to
the failing keyword) for better error context.

Also fixed Location field to use er.InstanceLocation for consistency with
schema_validation/validate_schema.go.
…idation errors, add KeywordLocation to schema violations

Pre-validation errors (compilation, missing response, IO read, JSON decode) now
correctly omit SchemaValidationFailure objects, as they don't represent actual
schema constraint violations.

Actual schema violations now include KeywordLocation (JSON Pointer path to the
failing keyword) for better error context.

Also fixed Location field to use er.InstanceLocation for consistency with
request validation and schema validation.
When a response header is marked as required in the OpenAPI schema and is
missing from the response, this is a schema constraint violation. Added
SchemaValidationFailure with full OpenAPI path context for KeywordLocation.

Updated ValidateResponseHeaders signature to accept pathTemplate and statusCode
to construct full JSON Pointer paths like:
  /paths/~1health/get/responses/200/headers/chicken-nuggets/required

This makes header validation consistent with request/response body validation,
which also uses full OpenAPI document paths for KeywordLocation.

Note: Considered using relative paths (/header-name/required) but chose full
paths for consistency with body validation patterns. Both approaches have
tradeoffs documented in PR description.
…r ReferenceSchema

- Render parameter schema once in path_parameters.go instead of in each error function
- Pass renderedSchema to all 8 path parameter error functions (bool, enum, integer, number, array variants)
- Update Context field to use raw base.Schema (programmatic access)
- Update ReferenceSchema field to use rendered JSON string (API consumers)
- Use full OpenAPI JSON Pointer paths for KeywordLocation (e.g., /paths/~1users~1{id}/parameters/id/schema/type)
- Serialize full schema objects for ReferenceSchema instead of just type strings
- Update resolveNumber and resolveInteger helpers to accept and pass renderedSchema

Note: This approach (Context=raw schema, ReferenceSchema=rendered string) will be reviewed later for consistency across the codebase
This directory was temporarily added during development but should not be ignored in version control.
Changes:
- Remove 'Build full OpenAPI path for KeywordLocation' comments
- Remove inline comments from previous commits
- Add renderedSchema parameter to QueryParameterMissing
- Set ReferenceSchema field in QueryParameterMissing SchemaValidationFailure
- Render schema for missing required parameters before creating error
- Update tests to pass renderedSchema parameter
Adds full OpenAPI context to all 7 header parameter error functions:
- HeaderParameterMissing
- HeaderParameterCannotBeDecoded (now includes SchemaValidationFailure)
- IncorrectHeaderParamEnum
- InvalidHeaderParamInteger
- InvalidHeaderParamNumber
- IncorrectHeaderParamBool
- IncorrectHeaderParamArrayBoolean
- IncorrectHeaderParamArrayNumber

All errors now include:
- KeywordLocation: Full JSON Pointer from OpenAPI root (e.g., /paths/{path}/{method}/parameters/{name}/schema/type)
- ReferenceSchema: Rendered schema as JSON string
- Context: Raw base.Schema object
- Proper FieldName and InstancePath

Updated ValidateHeaderArray to accept and pass path/operation/schema context.
Updated all test cases to pass new required parameters.
Adds full OpenAPI context to all 6 cookie parameter error functions:
- InvalidCookieParamInteger
- InvalidCookieParamNumber
- IncorrectCookieParamBool
- IncorrectCookieParamEnum
- IncorrectCookieParamArrayBoolean
- IncorrectCookieParamArrayNumber

All errors now include:
- KeywordLocation: Full JSON Pointer from OpenAPI root (e.g., /paths/{path}/{method}/parameters/{name}/schema/type)
- ReferenceSchema: Rendered schema as JSON string
- Context: Raw base.Schema object
- Proper FieldName and InstancePath

Updated ValidateCookieArray to accept and pass path/operation/schema context.
Updated all test cases to pass new required parameters.

This completes consistent SchemaValidationFailure population across all parameter types (path, query, header, cookie).
Removed the deprecated Location field entirely from SchemaValidationFailure struct
and updated all code and tests to use KeywordLocation instead.

Changes:
- Removed Location field from SchemaValidationFailure struct
- Updated Error() method to use FieldPath instead of Location
- Removed .Location assignment in schema_validation/validate_document.go
- Updated all test assertions to use KeywordLocation instead of Location
- Updated tests to reflect that schema compilation errors do not have
  SchemaValidationFailure objects (they were removed in earlier commits)

This completes the transition to the new error reporting model where:
- KeywordLocation: Full JSON Pointer to schema keyword (for all schema violations)
- FieldPath: JSONPath to the failing instance (for body validation)
- InstancePath: Structured path segments to failing instance
- Location field: Removed entirely
Creates helper functions in helpers package for constructing RFC 6901-compliant
JSON Pointer paths to OpenAPI specification locations.

New functions:
- EscapeJSONPointerSegment: Escapes ~  and / characters per RFC 6901
- ConstructParameterJSONPointer: Builds paths for parameter schemas
- ConstructResponseHeaderJSONPointer: Builds paths for response headers

This eliminates duplication of the escaping logic across 72+ locations in
the codebase and provides a single source of truth for JSON Pointer construction.

Pattern:
  Before: Manual escaping in each error function (3 lines of code each)
  After: Single function call with semantic naming

Next step: Refactor all existing inline JSON Pointer construction to use
these helpers.
Replaces all manual JSON Pointer construction with calls to the new helper
functions, eliminating 72+ instances of duplicated escaping logic.

Changes:
- errors/parameter_errors.go: Replaced all manual escaping with
  helpers.ConstructParameterJSONPointer() calls
  - All 35 parameter error functions now use helper
  - Handles type, enum, items/type, items/enum, maxItems, minItems, uniqueItems
- responses/validate_headers.go: Replaced manual escaping with
  helpers.ConstructResponseHeaderJSONPointer()
- errors/validation_error_test.go: Updated tests to use FieldPath instead of
  deprecated Location field

Benefits:
- Single source of truth for JSON Pointer construction
- Reduced code duplication (3 lines → 1 line per usage)
- More maintainable and less error-prone
- Semantic function names make intent clearer

Each function call reduced from:
  escapedPath := strings.ReplaceAll(pathTemplate, "~", "~0")
  escapedPath = strings.ReplaceAll(escapedPath, "/", "~1")
  escapedPath = strings.TrimPrefix(escapedPath, "~1")
  keywordLocation := fmt.Sprintf("/paths/%s/%s/...", escapedPath, ...)

To:
  keywordLocation := helpers.ConstructParameterJSONPointer(path, method, param, keyword)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant