Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

algae14's avatar

API Error Reporting

Ok, so I have this code in the handle() method of a Job called CreateSubscription.php:

{

    // Make sure dates provided to Job are chronologically valid

    if ($this->data['starts_on'] >= $this->data['ends_on']) 
    {
        dd('End date has to be greater than start date');
    }
    
    // Insert records in the database

}

Basically, I want to insert records in the database as long as the dates (supplied by an API call) validation checks out. The store method of my SubscriptionController.php calls the job as follows:

{
    // Dispatch synchronous job to create subscription
    $subscription = CreateSubscription::dispatchNow($request->validated());

    // All is saved to the database, now return the new subscription.
    return new SubscriptionResource($subscription);
}

The above is the controller and method that my API calls.

My question is this: I want to replace the dd() in CreateSubscription.php with proper error reporting back to the API/user. What is the best way of doing this since the API is typically expecting the subscription resource (formatted by SubscriptionResource)?

Should I actually be doing this date validation in my Form Request class?

My Form Request class (StoreSubscription.php) is simple. The rule() method is as follows.

{
    return [
        'name' => 'required | min:3',
        'aum' => 'numeric',
        'first_name' => 'required',
        'last_name' => 'required',
        'email' => 'required',
        'phone' => 'required',
        'starts_on' => 'required',
        'ends_on' => 'required',
        'plan_id' => 'required'
    ];
}

I get the two dates in there, and validate that they have been supplied in the API request. I don't do any chronological validation, however, in the Form Request class. Should I? Or is it better relegated to the Job responsible for persisting the subscription with the correct date chronology. The dates I am referring to are "starts_on" and "ends_on". Any help would be appreciated.

0 likes
8 replies
ftiersch's avatar

For user feedback you need to validate in the form request (check out https://laravel.com/docs/5.8/validation#rule-after, should be very easy :)).

Reason is this: Wenn you dispatch a job it isn't actually handled by your request. That's the whole point -> you save a job, that could take very long, somewhere and then let it be handled on the server. So the user doesn't have to wait for his request to finish.

That of course also means that the request for the user is already returned, so you can't display a validation error.

That being said I'd still say you should "validate" the dates in the job too (in case it's dispatched somewhere else with wrong dates) but then just save a log message or send an email or something like that.

algae14's avatar

@FTIERSCH - Thanks for your help. I'm definitely going to validate any form that goes through this controller method. But, as of now, only a REST API call will be calling SubscriptionController@store. This is why I'm trying to figure out the best way to return back to the caller the error that I currently have inside the dd().

Any thoughts?

ftiersch's avatar

@ALGAE14 - You can't get that error message because it is processed at another time (possibly even on another server). That's the whole point behind dispatching a Job.

So in order to return the error back to the caller you will need to validate it in your FormRequest :)

algae14's avatar

@FTIERSCH - Thank you. I moved it to my Form Request as follows.

public function withValidator($validator)
{

    $validator->after(function ($validator) 
    {
        if (!$this->validateDateChronology($this->only(['starts_on', 'ends_on']))) 
        {
            $validator->errors()
            ->add('ends_on', 'Subscription end date must come after start date');
        }
    });


}

Works like a charm if I use an actual form (i.e., create.blade.php). But, my problem is still not quite solved. I'm calling the controller from an API. So when I send invalid dates to my store method, I need to give back a response to the API caller with the error message that appears on the form.

How could I do that?

ftiersch's avatar

@ALGAE14 - I don't think you need to make it that complicated. Just extend your rule() method with 'required|after:starts_on' for the ends_on key, that should accomplish the same thing. If you want to customize the error message you can do that in the messages() method.

If you have that in place then it should automatically return the error message as a json object to your API caller. Does it work if you pass other wrong data (like if you don't pass an email address)? Do you get validation errors then?

algae14's avatar

@FTIERSCH - So, I implemented the 'required|after:starts_on' in my rules() method for my Form Request class. Very cool, by the way. Thanks!

But, when I call the API from Postman with bad dates, I don't get back JSON in the body. Instead I get back a 404 status code with the HTML in the body.

I get the following in the body. No JSON with my validation's error message.

Not Found html, body { background-color: #fff; color: #636b6f; font-family: 'Nunito', sans-serif; font-weight: 100; height: 100vh; margin: 0; }

        .full-height {
            height: 100vh;
        }

        .flex-center {
            align-items: center;
            display: flex;
            justify-content: center;
        }

        .position-ref {
            position: relative;
        }

        .code {
            border-right: 2px solid;
            font-size: 26px;
            padding: 0 15px 0 15px;
            text-align: center;
        }

        .message {
            font-size: 18px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="flex-center position-ref full-height">
        <div class="code">
            404            </div>
        <div class="message" style="padding: 10px;">
            Not Found            </div>
    </div>
</body>

ftiersch's avatar

But it works with correct dates? That would be weird.

To get JSON errors back you need to send a request that tells Laravel that this is supposed to be an AJAX request. You can send the Content-Type header with "application/json", that should do the trick :)

algae14's avatar
algae14
OP
Best Answer
Level 3

@FTIERSCH - Ok, so I solved it. I implemented the failedValidation() method in my Form Request. Turns out the Form Request by default just spits out HTML when it fails. So, I jut needed to make sure that it spits-out JSON for my api routes.

Thanks for all your help.

protected function failedValidation(Validator $validator)
{
    // Only spit-out JSON if the request came from an API call. Web requests can respond as normal with HTML.
    if (request()->is('api*')) {
        throw new HttpResponseException(response()->json($validator->errors(), JsonResponse::HTTP_UNPROCESSABLE_ENTITY));
    }   
}

Please or to participate in this conversation.