Returning error if the validation fails in laravel
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering AJAX Validation Errors in Laravel: Returning Structured JSON Responses
As developers building modern web applications, especially those leveraging AJAX for dynamic data fetching and form submissions, handling validation errors gracefully is paramount. When an AJAX request fails validation, we don't just want a generic HTTP 422 response; we want structured, machine-readable error details returned in JSON so the frontend can display specific feedback to the user.
The scenario you described—performing manual validation and expecting JSON errors instead of the default behavior—is very common. Let's dive into why this happens and how we can implement a robust solution using best practices in Laravel.
The Default Behavior: Why You See 422
When you use $request->validate($rules), if the input data fails validation, Laravel throws a Illuminate\Validation\ValidationException. By default, when this exception is caught by the framework and sent back to the client (especially in API contexts), it results in an HTTP status code of 422 Unprocessable Entity. This status code correctly signals that the server understood the request but could not process the data due to validation failures.
The reason you didn't see the errors directly in your initial JSON response is likely because the exception handling mechanism intercepts the flow before you can manually construct a custom error payload within the same method execution stream, or you might be missing the specific step to extract the message bag correctly from the failed validation attempt.
Solution 1: The Recommended Approach – Using Form Requests
The most elegant and maintainable way to handle validation in Laravel is by separating validation logic from your controller methods using Form Requests. This keeps your controllers clean and centralizes the business rules, which aligns perfectly with the principles of well-structured code found on platforms like laravelcompany.com.
When you use a Form Request, if validation fails, Laravel automatically handles the response structure for you when used within an API context (often by using validate() or relying on HTTP middleware).
Example using a Form Request:
Create a Form Request:
php artisan make:request StoreCategoryRequestDefine Validation Rules in the Request:
InStoreCategoryRequest.php, define your rules:public function rules() { return [ 'title' => 'required|string|max:255', 'parent_id' => 'nullable|integer', 'priority' => 'required|integer', // ... other rules ]; }Use the Request in Your Controller:
In your controller, you simply callvalidate(). If this fails, you can handle the resulting exception or use a more advanced approach (see Solution 2) if you absolutely need to return custom JSON instead of throwing an exception.
Solution 2: Manually Retrieving Errors for Custom JSON Responses
If you insist on manually checking the validation result within your controller and returning a specific JSON error structure (which is common in complex AJAX scenarios), you must ensure you are correctly accessing the error messages generated by the validate() method.
Your initial attempt was very close, but we need to ensure the logic flows cleanly:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response; // Assuming this is used for response return
public function store(Request $request)
{
// 1. Define the rules (or use a Form Request object if you implemented one)
$rules = $this->category->getRules(); // Assuming category model has a method to get rules
// 2. Attempt Validation and Check Failure
$validated = $request->validate($rules);
if ($validated === false) {
// If validate() fails, it throws an exception by default unless configured otherwise.
// For manual JSON control, we must check the result carefully or use a custom approach.
// A safer way is to rely on catching exceptions if you want to stop execution here.
// However, if you need to return the error data *without* throwing an exception for 422:
$errors = $request->getErrors(); // Accessing errors directly from the request object
return response()->json([
'success' => false,
'errors' => $errors // This will contain the detailed validation messages
], 400); // Use 400 Bad Request for client-side input errors
}
// 3. Proceed with saving data if validation passed
$data = $request->all();
$data['title'] = $request->title;
// ... map other fields
$this->category->fill($data);
$status = $this->category->save();
if ($status) {
return response()->json(['status' => true, 'data' => 'Category created successfully.']);
} else {
return response()->json(['status' => false, 'data' => null], 500); // Use 500 for server errors
}
}
Key Takeaway: Instead of relying solely on $request->validate($rules)->fails(), which often leads to an automatic exception flow, it is more explicit and reliable in API development to check the state or use methods like $request->errors() after attempting validation, ensuring your JSON payload is intentionally constructed for the client. Always remember that leveraging Laravel's built-in features, like those found on laravelcompany.com, leads to more resilient and readable code.
Conclusion
Handling validation errors in an AJAX context requires careful thought about HTTP status codes and JSON structure. While manually checking $request->validate() is possible, the most professional approach is to adopt Form Requests to handle the primary validation layer. If you must return custom error messages directly from the controller for specific API needs, explicitly check the validation result and use methods like $request->errors() to construct a precise JSON response detailing exactly what went wrong. By mastering these techniques, you can ensure your application provides clear, actionable feedback to every user.