Update beads metadata
Fix Form_Utils bugs and unify error handling documentation Protect framework files from auto-modification when not in developer mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -110,9 +110,9 @@ Error responses:
|
||||
```json
|
||||
{
|
||||
"_success": false,
|
||||
"error_type": "response_form_error",
|
||||
"reason": "Validation failed",
|
||||
"details": { /* error details */ }
|
||||
"error_code": "validation",
|
||||
"message": "Please correct the errors below",
|
||||
"errors": { "field_name": "Error message" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -189,15 +189,15 @@ class User_Controller extends Rsx_Controller
|
||||
public static function get_profile(Request $request, array $params = [])
|
||||
{
|
||||
$user_id = $params['user_id'] ?? null;
|
||||
|
||||
|
||||
if (!$user_id) {
|
||||
return response_form_error('User ID required', ['user_id' => 'Missing']);
|
||||
return response_error(Ajax::ERROR_VALIDATION, ['user_id' => 'User ID required']);
|
||||
}
|
||||
|
||||
|
||||
$user = User::find($user_id);
|
||||
|
||||
|
||||
if (!$user) {
|
||||
return response_form_error('User not found', ['user_id' => 'Invalid']);
|
||||
return response_error(Ajax::ERROR_NOT_FOUND, 'User not found');
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -218,14 +218,19 @@ Normal responses (arrays, objects) are automatically filtered through `json_deco
|
||||
|
||||
This prevents memory leaks and ensures clean data structures.
|
||||
|
||||
## Special Response Types
|
||||
## Error Response Helper
|
||||
|
||||
The following helper functions create special responses that are handled differently:
|
||||
Use `response_error()` with error codes from the `Ajax` class:
|
||||
|
||||
- `response_auth_required($reason, $redirect)` - Throws `AjaxAuthRequiredException`
|
||||
- `response_unauthorized($reason, $redirect)` - Throws `AjaxUnauthorizedException`
|
||||
- `response_form_error($reason, $details)` - Throws `AjaxFormErrorException` with extractable details
|
||||
- `response_fatal_error($reason, $details)` - Throws `AjaxFatalErrorException`
|
||||
```php
|
||||
return response_error(Ajax::ERROR_VALIDATION, ['field' => 'Error message']);
|
||||
return response_error(Ajax::ERROR_NOT_FOUND, 'Resource not found');
|
||||
return response_error(Ajax::ERROR_UNAUTHORIZED);
|
||||
return response_error(Ajax::ERROR_AUTH_REQUIRED);
|
||||
return response_error(Ajax::ERROR_FATAL, 'Something went wrong');
|
||||
```
|
||||
|
||||
**Error codes:** `ERROR_VALIDATION`, `ERROR_NOT_FOUND`, `ERROR_UNAUTHORIZED`, `ERROR_AUTH_REQUIRED`, `ERROR_FATAL`, `ERROR_GENERIC`
|
||||
|
||||
## Security Considerations
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ class Form_Utils {
|
||||
// Resolve the promise once all animations are complete
|
||||
Promise.all(animations).then(() => {
|
||||
// Scroll to error container if it exists
|
||||
const $error_container = $parent.find('[data-id="error_container"]').first();
|
||||
const $error_container = $parent.find('[$sid="error_container"]').first();
|
||||
if ($error_container.length > 0) {
|
||||
const container_top = $error_container.offset().top;
|
||||
|
||||
@@ -177,8 +177,8 @@ class Form_Utils {
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (error.type === 'form_error' && error.details) {
|
||||
await Form_Utils.apply_form_errors(form_selector, error.details);
|
||||
if (error.code === Ajax.ERROR_VALIDATION && error.metadata) {
|
||||
await Form_Utils.apply_form_errors(form_selector, error.metadata);
|
||||
} else {
|
||||
await Form_Utils.apply_form_errors(form_selector, error.message || 'An error occurred');
|
||||
}
|
||||
@@ -345,7 +345,7 @@ class Form_Utils {
|
||||
*/
|
||||
static _apply_combined_error($parent, summary_msg, unmatched_errors) {
|
||||
const animations = [];
|
||||
const $error_container = $parent.find('[data-id="error_container"]').first();
|
||||
const $error_container = $parent.find('[$sid="error_container"]').first();
|
||||
const $target = $error_container.length > 0 ? $error_container : $parent;
|
||||
|
||||
// Create alert with summary message and bulleted list of unmatched errors
|
||||
@@ -386,7 +386,7 @@ class Form_Utils {
|
||||
const animations = [];
|
||||
|
||||
// Look for a specific error container div (e.g., in Rsx_Form component)
|
||||
const $error_container = $parent.find('[data-id="error_container"]').first();
|
||||
const $error_container = $parent.find('[$sid="error_container"]').first();
|
||||
const $target = $error_container.length > 0 ? $error_container : $parent;
|
||||
|
||||
if (typeof messages === 'string') {
|
||||
|
||||
@@ -857,10 +857,10 @@ class Rsx {
|
||||
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
||||
</div>
|
||||
`;
|
||||
} else if (error.type === 'form_error' && error.details) {
|
||||
} else if (error.code === Ajax.ERROR_VALIDATION && error.metadata) {
|
||||
// Validation errors - show unmatched errors only
|
||||
// (matched errors should be handled by Form_Utils.apply_form_errors)
|
||||
const errors = error.details;
|
||||
const errors = error.metadata;
|
||||
const error_list = [];
|
||||
|
||||
for (const field in errors) {
|
||||
|
||||
Reference in New Issue
Block a user