Enhanced Validation Errors
Open Register has been enhanced with improved validation error messages that provide much clearer and more user-friendly feedback compared to the standard JSON Schema validation library errors.
Problem
Previously, when validation failed, users would receive generic error messages like:
The required properties ({missing}) are missing- 'Invalid object'
- Generic type mismatch errors
These messages didn't tell users exactly which properties were missing or what the specific validation issues were.
Error Flow Comparison
graph TD
A[Object Validation] --> B{Validation Result}
subgraph "Before: Generic Messages"
B --> C[Opis Error Message]
C --> D["The required properties ({missing}) are missing"]
D --> E[Confused User]
end
subgraph "After: Clear Messages"
B --> F[Enhanced Error Processing]
F --> G["The required property 'title' is missing"]
G --> H[User Knows What to Fix]
end
Solution
A streamlined approach that enhances validation error messages directly within the existing ValidateObject service, requiring no additional dependencies or complex configuration.
Implementation
Simplified Validation Flow
The enhanced validation system works through a streamlined approach without additional dependencies:
sequenceDiagram
participant User
participant ObjectService
participant ValidateObject
participant OpisValidator as Opis JsonSchema
User->>ObjectService: Create/Update Object
ObjectService->>ValidateObject: validateObject()
ValidateObject->>OpisValidator: validate()
OpisValidator-->>ValidateObject: ValidationResult
alt Validation Failed
ValidateObject->>ValidateObject: generateErrorMessage()
Note over ValidateObject: Built-in error formatting logic
ValidateObject-->>ObjectService: Meaningful Error Message
ObjectService->>ObjectService: throw ValidationException(meaningfulMessage)
ObjectService-->>User: Clear Error Response
else Validation Passed
ValidateObject-->>ObjectService: Valid Result
ObjectService-->>User: Success Response
end
Built-in Error Formatting
The ValidateObject class now includes built-in error formatting methods that provide detailed error messages for various validation scenarios:
- Required Properties: 'The required property email is missing'
- Type Mismatches: 'Property age should be of type integer but is string'
- Format Validation: 'Property email should match the format email but the value invalid-email does not'
- Length Constraints: 'Property name should have at least 3 characters, but has 1'
- Value Ranges: 'Property age should be at least 18, but is 16'
- Enum Values: 'Property status should be one of: active, inactive, pending, but is deleted'
Integration
The enhanced error formatting is automatically used throughout the validation system through a simple, streamlined approach:
- ValidateObject Handler: Contains built-in error formatting logic in the
generateErrorMessage()method - ObjectService: Updated to use meaningful error messages instead of generic Opis messages
- Error Response: Provides both summary and detailed error information
- No Additional Dependencies: No need for separate classes or dependency injection
Key Improvement: Built-in generateErrorMessage()
The solution was simplified by implementing the error formatting logic directly in the ValidateObject class. This method:
- Intercepts Generic Messages: Catches the generic Opis error messages before they reach the user
- Built-in Formatting: Processes validation errors through built-in formatting logic
- Returns Clear Messages: Provides specific, actionable error messages
- Maintains Context: Preserves all technical details for debugging while presenting user-friendly messages
- Zero Dependencies: No additional classes or configuration needed
Before (in ObjectService.php):
if ($result->isValid() === false) {
throw new ValidationException($result->error()->message(), errors: $result->error());
// Generic message: 'The required properties ({missing}) are missing'
}
After (in ObjectService.php):
if ($result->isValid() === false) {
$meaningfulMessage = $this->validateHandler->generateErrorMessage($result);
throw new ValidationException($meaningfulMessage, errors: $result->error());
// Clear message: 'The required property title is missing'
}
Error Response Structure
{
'status': 'error',
'message': 'Validation failed',
'errors': [
{
'property': 'email',
'keyword': 'required',
'message': 'The required property 'email' is missing',
'value': null,
'path': ['email'],
'schemaPath': ['required']
}
]
}
Real-World API Response Examples
Missing Required Properties:
{
'status': 'error',
'message': 'Validation failed',
'errors': [
{
'property': null,
'message': 'The required property 'title' is missing'
}
]
}
Type Mismatch:
{
'status': 'error',
'message': 'Validation failed',
'errors': [
{
'property': 'age',
'message': 'Property 'age' should be of type 'integer' but is 'string''
}
]
}
Multiple Validation Errors:
{
'status': 'error',
'message': 'Validation failed',
'errors': [
{
'property': null,
'message': 'The required properties (name, email, address) are missing'
}
]
}
Benefits
- Improved User Experience: Users get clear, actionable error messages
- Faster Development: Developers can quickly identify validation issues
- Better API Documentation: Clear error responses help with API integration
- Reduced Support: Fewer questions about unclear error messages
- Simple Implementation: No additional dependencies or complex setup
- Maintainable: All logic contained within existing service structure
Technical Implementation
Compatibility with Opis JsonSchema 2.3.0
The enhanced error formatter was specifically updated to work with Opis JsonSchema version 2.3.0, which has different method signatures compared to newer versions:
Key API Changes Handled:
- Data Path Access: Uses
$error->data()->fullPath()instead of$error->dataPointer() - Value Access: Uses
$error->data()->value()instead of direct$error->data() - Error Arguments: Properly accesses validation parameters through
$error->args() - Schema Information: Simplified schema path generation to work with available API methods
Method Mappings:
// Old (incompatible) approach:
$dataPointer = $error->dataPointer(); // Method doesn't exist in 2.3.0
$schemaPointer = $error->schemaPointer(); // Method doesn't exist in 2.3.0
// New (compatible) approach:
$dataPath = $error->data()->fullPath(); // Works with 2.3.0
$value = $error->data()->value(); // Works with 2.3.0
$args = $error->args(); // Works with 2.3.0
Files Changed
Modified Files
lib/Service/ObjectHandlers/ValidateObject.php- Added built-in enhanced error formatting methodslib/Service/ObjectService.php- Updated to use meaningful error messages
Approach Benefits
- Simple: No new classes or dependencies required
- Maintainable: All error formatting logic in one place
- Efficient: Direct implementation without additional overhead
- Reliable: Uses existing infrastructure without new injection points
This streamlined approach provides all the benefits of enhanced validation error messages while maintaining simplicity and avoiding additional complexity in the codebase.