Errors and feedback
API error shapes and response conventions for control-table endpoints
Consistent response shapes help both backend and frontend developers. The React ApiTables module expects predictable JSON — especially success, errors, and message.
Golden rules
- Always include
success— boolean on every action response - Use
errorsas array for user-facing messages (supports i18n) - Do not mix success and errors —
success: falseshould haveerrors, notdata - Instant export returns file stream — not JSON
Success envelope
Controllers wrap structure and query responses:
{ "success": true, "columns": [], "items": [] }Action callbacks you write should follow the same pattern:
return ['success' => true, 'message' => 'Saved'];Error envelope
Package-built error (undefined action):
{
"success": false,
"errors": ["Action is not defined", "إجراء غير معرف"]
}HTTP 422. Your callbacks should match:
return [
'success' => false,
'errors' => ['This order cannot be archived'],
];Validation errors
Row bulk actions validate selected_ids:
$request->validate(['selected_ids' => 'required|array|min:1']);Laravel returns standard 422 with:
{
"message": "The selected ids field is required.",
"errors": { "selected_ids": ["The selected ids field is required."] }
}How frontend handles responses
| Response | UI behavior |
|---|---|
success === true | Success callback; optional success toast |
errors (array) | One error toast per item |
errors (string) | Single error toast |
message without success | Treated as error toast |
| 401 | Redirect to login (frontend axios interceptor) |
Design messages for end users, not developers — they appear in toasts.
Export-specific responses
Instant Excel (export_excel)
Success returns download metadata:
{
"type": "stream",
"file_name": "users-1234567890.xlsx",
"data": { "url": "https://..." }
}Over 3,000 rows:
{
"success": false,
"errors": ["Results exceed 3000 ... use email export"]
}Email report
Success returns immediately while file generates async:
return ['success' => true, 'message' => 'Report queued'];User receives email when queue processes — not synchronous.
Bilingual errors
Built-in package messages include English and Arabic in the same errors array. For custom messages, follow team convention — either single locale per request (via Accept-Language) or both strings.
Debugging checklist
| Issue | Check |
|---|---|
| Frontend shows generic error | Does response include errors or message? |
| Action succeeds but UI does not refresh | Return correct onSuccess in action definition |
| 422 with empty body | Validation failed — check Laravel validation response |
| Export works in Postman, not UI | CORS, blob handling — coordinate with frontend |