This is a multi-layered issue involving logging configuration, error handling, validation logic, and API design. Let me address each focus area comprehensively:
Validation Logging Configuration:
The validation logging is likely set to ERROR level only, which doesn’t capture validation failures that are handled as business logic rather than errors. Update your logging configuration:
log4j.logger.com.rockwell.mes.workorder.validation=DEBUG
log4j.logger.com.rockwell.mes.workorder.transition=DEBUG
log4j.logger.com.rockwell.mes.api.workorder=DEBUG
Also enable validation audit logging specifically:
workorder.validation.auditEnabled=true
workorder.validation.auditLevel=DETAILED
workorder.validation.logFailures=true
workorder.transition.logAttempts=true
With these settings, every transition attempt will be logged with full context including which validation rules were evaluated and which ones failed. The logs will show the exact reason for rejection even if the API doesn’t return it.
Error Message Handling:
The API is using an anti-pattern where it returns HTTP 200 with a generic success flag instead of proper HTTP status codes and detailed error responses. The response structure is probably:
{
"success": true,
"message": "Request processed",
"data": {
"statusChanged": false,
"validationErrors": []
}
}
The outer success:true indicates the API call was processed, but statusChanged:false shows the transition didn’t happen. Your client code needs to check the inner data object, not just the outer success flag:
// Pseudocode - Proper response handling:
1. Parse API response JSON
2. Check outer success flag (indicates API call processed)
3. Extract inner data.statusChanged boolean
4. If statusChanged == false, extract data.validationErrors array
5. Display validation errors to user
6. Log full response for debugging
The validationErrors array will contain the actual rejection reasons, but only if validation logging is configured correctly. Without proper logging config, this array remains empty even when validations fail.
Transition Rule Validation:
The transition rule validation logic needs defensive error handling. The current implementation probably looks like:
try {
validateTransition(workOrder, targetStatus);
executeTransition(workOrder, targetStatus);
return success(true);
} catch (Exception e) {
return success(true); // BUG: Should return error
}
This catch-all exception handler returns success regardless of what happened. The validation exceptions are being swallowed. The correct implementation should be:
// Pseudocode - Proper validation error handling:
1. Create validation context with work order and target status
2. Execute each validation rule sequentially
3. Collect all validation failures (don't stop at first failure)
4. If any validation failed:
a. Log all validation failures with full context
b. Return HTTP 400 with validation error details
c. DO NOT execute the transition
5. If all validations passed:
a. Execute the status transition
b. Return HTTP 200 with updated work order
6. Handle exceptions separately from validation failures
Validation failures are expected business logic, not exceptions. They should be handled explicitly and returned as structured error responses, not caught in a generic exception handler.
API Response Design:
The API needs to follow REST conventions properly. For your transition endpoint:
POST /api/workorder/{id}/transition
Request: {
"targetStatus": "IN_PROGRESS",
"reason": "Production started",
"operator": "OP-123"
}
Success Response (HTTP 200):
{
"workOrderId": "12345",
"previousStatus": "RELEASED",
"currentStatus": "IN_PROGRESS",
"transitionedAt": "2024-11-18T14:45:00Z",
"transitionedBy": "OP-123"
}
Validation Failure Response (HTTP 400):
{
"error": "ValidationFailed",
"message": "Work order transition validation failed",
"validationErrors": [
{
"rule": "MaterialAvailability",
"field": "materialAllocations",
"message": "Required material M-001 not allocated",
"severity": "ERROR"
},
{
"rule": "ResourceAvailability",
"field": "workCenter",
"message": "Work center WC-101 not available",
"severity": "ERROR"
}
]
}
State Conflict Response (HTTP 409):
{
"error": "InvalidStateTransition",
"message": "Cannot transition from COMPLETED to IN_PROGRESS",
"currentStatus": "COMPLETED",
"requestedStatus": "IN_PROGRESS",
"allowedTransitions": ["CLOSED"]
}
HTTP 200 should ONLY be returned when the transition actually succeeded. Use HTTP 400 for validation failures and HTTP 409 for invalid state transitions. This makes error handling explicit and unambiguous.
Debugging the Current Issue:
To diagnose your immediate problem:
- Enable DEBUG logging as shown above
- Attempt a transition that’s failing
- Search logs for “transition” and “validation” keywords
- Look for validation rule names (MaterialAvailability, ResourceAvailability, OperatorAssignment, etc.)
- Identify which specific validation is failing
Common validation failures that cause silent rejections:
- Material Allocation: Required materials not allocated or insufficient quantity
- Resource Assignment: Work center or equipment not assigned or unavailable
- Operator Credentials: Operator not qualified for the operation
- Routing: Work order routing not defined or invalid sequence
- Quantity Validation: Work order quantity doesn’t match planned quantity
- Custom Attributes: Required custom fields missing or invalid values
Each of these has a specific validation rule. Once you identify which rule is failing, you can fix the work order data or adjust the validation rule configuration.
Immediate Workaround:
While fixing the API response design, implement client-side validation that checks prerequisites before attempting the transition. Query the work order details and validate:
// Pseudocode - Client-side pre-validation:
1. GET /api/workorder/{id} to retrieve full work order details
2. Check materials are allocated (materialAllocations.length > 0)
3. Check work center is assigned (workCenter != null)
4. Check operator is assigned (operator != null)
5. Check current status allows transition (validTransitions includes target)
6. Only POST transition request if all checks pass
7. If checks fail, display specific error to user
This prevents silent failures by catching validation issues before calling the API. However, this is a workaround - the proper fix is to implement correct error handling in the API itself.
Long-Term Solution:
The root cause is inadequate error handling architecture. Implement these changes:
- Create a ValidationResult class that explicitly tracks success/failure and error details
- Separate validation logic from transition execution
- Return proper HTTP status codes (200/400/409) based on validation results
- Include detailed validation error information in API responses
- Log all validation attempts with full context regardless of outcome
- Implement structured error responses with machine-readable error codes
This ensures validation failures are visible, traceable, and actionable rather than silent. The API consumer gets clear feedback about what went wrong and how to fix it, and operations teams can troubleshoot issues using comprehensive logs.
For your immediate production issue, enable DEBUG logging first to identify which validation is failing, then fix the underlying data issue (probably missing material allocation or work center assignment). The API design fixes can be implemented in a subsequent release.