Fix code quality violations for publish
Remove unused blade settings pages not linked from UI Convert remaining frontend pages to SPA actions Convert settings user_settings and general to SPA actions Convert settings profile pages to SPA actions Convert contacts and projects add/edit pages to SPA actions Convert clients add/edit page to SPA action with loading pattern Refactor component scoped IDs from $id to $sid Fix jqhtml comment syntax and implement universal error component system Update all application code to use new unified error system Remove all backwards compatibility - unified error system complete Phase 5: Remove old response classes Phase 3-4: Ajax response handler sends new format, old helpers deprecated Phase 2: Add client-side unified error foundation Phase 1: Add server-side unified error foundation Add unified Ajax error response system with constants 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,16 @@
|
||||
* Batches up to 20 calls or flushes after setTimeout(0) debounce.
|
||||
*/
|
||||
class Ajax {
|
||||
// Error code constants (must match server-side Ajax::ERROR_* constants)
|
||||
static ERROR_VALIDATION = 'validation';
|
||||
static ERROR_NOT_FOUND = 'not_found';
|
||||
static ERROR_UNAUTHORIZED = 'unauthorized';
|
||||
static ERROR_AUTH_REQUIRED = 'auth_required';
|
||||
static ERROR_FATAL = 'fatal';
|
||||
static ERROR_GENERIC = 'generic';
|
||||
static ERROR_SERVER = 'server_error'; // Client-generated (HTTP 500)
|
||||
static ERROR_NETWORK = 'network_error'; // Client-generated (connection failed)
|
||||
|
||||
/**
|
||||
* Initialize Ajax system
|
||||
* Called automatically when class is loaded
|
||||
@@ -198,81 +208,70 @@ class Ajax {
|
||||
resolve(processed_value);
|
||||
} else {
|
||||
// Handle error responses
|
||||
const error_type = response.error_type || 'unknown_error';
|
||||
const reason = response.reason || 'Unknown error occurred';
|
||||
const details = response.details || {};
|
||||
const error_code = response.error_code || Ajax.ERROR_GENERIC;
|
||||
const reason = response.reason || 'An error occurred';
|
||||
const metadata = response.metadata || {};
|
||||
|
||||
// Handle specific error types
|
||||
switch (error_type) {
|
||||
case 'fatal':
|
||||
// Fatal PHP error with full error details
|
||||
const fatal_error_data = response.error || {};
|
||||
const error_message = fatal_error_data.error || 'Fatal error occurred';
|
||||
// Create error object
|
||||
const error = new Error(reason);
|
||||
error.code = error_code;
|
||||
error.metadata = metadata;
|
||||
|
||||
console.error('Ajax error response from server:', response.error);
|
||||
// Handle fatal errors specially
|
||||
if (error_code === Ajax.ERROR_FATAL) {
|
||||
const fatal_error_data = response.error || {};
|
||||
error.message = fatal_error_data.error || 'Fatal error occurred';
|
||||
error.metadata = response.error;
|
||||
|
||||
const fatal_error = new Error(error_message);
|
||||
fatal_error.type = 'fatal';
|
||||
fatal_error.details = response.error;
|
||||
console.error('Ajax error response from server:', response.error);
|
||||
|
||||
// Log to server if browser error logging is enabled
|
||||
Debugger.log_error({
|
||||
message: `Ajax Fatal Error: ${error_message}`,
|
||||
type: 'ajax_fatal',
|
||||
endpoint: url,
|
||||
details: response.error,
|
||||
});
|
||||
|
||||
reject(fatal_error);
|
||||
break;
|
||||
|
||||
case 'response_auth_required':
|
||||
console.error(
|
||||
'The user is no longer authenticated, this is a placeholder for future code which handles this scenario.'
|
||||
);
|
||||
const auth_error = new Error(reason);
|
||||
auth_error.type = 'auth_required';
|
||||
auth_error.details = details;
|
||||
reject(auth_error);
|
||||
break;
|
||||
|
||||
case 'response_unauthorized':
|
||||
console.error(
|
||||
'The user is unauthorized to perform this action, this is a placeholder for future code which handles this scenario.'
|
||||
);
|
||||
const unauth_error = new Error(reason);
|
||||
unauth_error.type = 'unauthorized';
|
||||
unauth_error.details = details;
|
||||
reject(unauth_error);
|
||||
break;
|
||||
|
||||
case 'response_form_error':
|
||||
const form_error = new Error(reason);
|
||||
form_error.type = 'form_error';
|
||||
form_error.details = details;
|
||||
reject(form_error);
|
||||
break;
|
||||
|
||||
default:
|
||||
const generic_error = new Error(reason);
|
||||
generic_error.type = error_type;
|
||||
generic_error.details = details;
|
||||
reject(generic_error);
|
||||
break;
|
||||
// Log to server
|
||||
Debugger.log_error({
|
||||
message: `Ajax Fatal Error: ${error.message}`,
|
||||
type: 'ajax_fatal',
|
||||
endpoint: url,
|
||||
details: response.error,
|
||||
});
|
||||
}
|
||||
|
||||
// Log auth errors for debugging
|
||||
if (error_code === Ajax.ERROR_AUTH_REQUIRED) {
|
||||
console.error('User is no longer authenticated');
|
||||
}
|
||||
if (error_code === Ajax.ERROR_UNAUTHORIZED) {
|
||||
console.error('User is unauthorized to perform this action');
|
||||
}
|
||||
|
||||
reject(error);
|
||||
}
|
||||
},
|
||||
error: (xhr, status, error) => {
|
||||
const error_message = Ajax._extract_error_message(xhr);
|
||||
const network_error = new Error(error_message);
|
||||
network_error.type = 'network_error';
|
||||
network_error.status = xhr.status;
|
||||
network_error.statusText = status;
|
||||
const err = new Error();
|
||||
|
||||
// Log server errors (500+) to the server if browser error logging is enabled
|
||||
// Determine error code based on status
|
||||
if (xhr.status >= 500) {
|
||||
// Server error (PHP crashed)
|
||||
err.code = Ajax.ERROR_SERVER;
|
||||
err.message = 'A server error occurred. Please try again.';
|
||||
} else if (xhr.status === 0 || status === 'timeout' || status === 'error') {
|
||||
// Network error (connection failed)
|
||||
err.code = Ajax.ERROR_NETWORK;
|
||||
err.message = 'Could not connect to server. Please check your connection.';
|
||||
} else {
|
||||
// Generic error
|
||||
err.code = Ajax.ERROR_GENERIC;
|
||||
err.message = Ajax._extract_error_message(xhr);
|
||||
}
|
||||
|
||||
err.metadata = {
|
||||
status: xhr.status,
|
||||
statusText: status
|
||||
};
|
||||
|
||||
// Log server errors to server
|
||||
if (xhr.status >= 500) {
|
||||
Debugger.log_error({
|
||||
message: `Ajax Server Error ${xhr.status}: ${error_message}`,
|
||||
message: `Ajax Server Error ${xhr.status}: ${err.message}`,
|
||||
type: 'ajax_server_error',
|
||||
endpoint: url,
|
||||
status: xhr.status,
|
||||
@@ -280,7 +279,7 @@ class Ajax {
|
||||
});
|
||||
}
|
||||
|
||||
reject(network_error);
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -376,26 +375,13 @@ class Ajax {
|
||||
});
|
||||
} else {
|
||||
// Handle error
|
||||
const error_type = call_response.error_type || 'unknown_error';
|
||||
let error_message;
|
||||
let error_details;
|
||||
|
||||
if (error_type === 'fatal' && call_response.error) {
|
||||
// Fatal PHP error with full error details
|
||||
const fatal_error_data = call_response.error;
|
||||
error_message = fatal_error_data.error || 'Fatal error occurred';
|
||||
error_details = call_response.error;
|
||||
|
||||
console.error('Ajax error response from server:', call_response.error);
|
||||
} else {
|
||||
// Other error types
|
||||
error_message = call_response.reason || 'Unknown error occurred';
|
||||
error_details = call_response.details || {};
|
||||
}
|
||||
const error_code = call_response.error_code || Ajax.ERROR_GENERIC;
|
||||
const error_message = call_response.reason || 'Unknown error occurred';
|
||||
const metadata = call_response.metadata || {};
|
||||
|
||||
const error = new Error(error_message);
|
||||
error.type = error_type;
|
||||
error.details = error_details;
|
||||
error.code = error_code;
|
||||
error.metadata = metadata;
|
||||
|
||||
pending_call.is_error = true;
|
||||
pending_call.error = error;
|
||||
@@ -410,7 +396,8 @@ class Ajax {
|
||||
// Network or server error - reject all pending calls
|
||||
const error_message = Ajax._extract_error_message(xhr_error);
|
||||
const error = new Error(error_message);
|
||||
error.type = 'network_error';
|
||||
error.code = Ajax.ERROR_NETWORK;
|
||||
error.metadata = {};
|
||||
|
||||
for (const call_id in call_map) {
|
||||
const pending_call = call_map[call_id];
|
||||
|
||||
Reference in New Issue
Block a user