Enhancing Your Laravel Job Handling with Middleware: Managing HttpClientException
 
    Laravel devs, here's a gem for you: π
If you're looking to improve the resilience and efficiency of your job handling in Laravel, leveraging middleware is a powerful approach. In this post, we'll explore how to use the ThrottlesExceptions middleware to handle failed HTTP requests gracefully and ensure your jobs stay robust even under intermittent failures.
Using Middleware in Laravel Jobs
Middleware in Laravel provides a way to filter HTTP requests entering your application. However, it can also be applied to queued jobs to control their execution flow. The ThrottlesExceptions middleware is particularly useful when dealing with external HTTP requests that may fail intermittently.
Example: The GetArticle Job
Let's dive into a practical example with the GetArticle job. This job fetches an article from a given URL, processes it, and stores it in the database. We'll add middleware to handle retries in case of failures.
Here's the complete code for the GetArticle job:
<?php
namespace App\Jobs;
use Http;
use App\Models\Article;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Http\Client\HttpClientException;
class GetArticle implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public function __construct(public string $url){}
    public function middleware()
    {
        return [
            (new ThrottlesExceptions(
                maxAttempts: 3, 
                decayMinutes: 5
            ))->by('service_id_here')
            ->backoff(1)
            ->when(function (Throwable $e) {
                return $e instanceof HttpClientException;
            })
        ];
    }
    public function handle()
    {
        $response = Http::acceptJson()
            ->timeout(10)
            ->get($this->url);
        if ($response->serverError()) {
            return $this->release(600);
        }
        $transformedData = Article::transform($response->json());
        Article::create($transformedData);
    }
}
GetArticle.php
Controller to Dispatch the Job
To complete the example, we need a controller to dispatch the GetArticle job. Here is a simple controller that accepts a URL and dispatches the job:
<?php
namespace App\Http\Controllers;
use App\Jobs\GetArticle;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ArticleController extends Controller
{
    public function fetchArticle(Request $request)
    {
        $url = $request->input('url');
        GetArticle::dispatch($url);
        return response()->json(['message' => 'Article fetch job has been dispatched.']);
    }
}
ArticleController.php
Route Definition
Next, define a route to handle the request and invoke the controller method:
use App\Http\Controllers\ArticleController;
Route::post('/fetch-article', [ArticleController::class, 'fetchArticle']);
routes/web.php
Breaking Down the Code
- Middleware Setup:
 Themiddlewaremethod in theGetArticlejob class sets up theThrottlesExceptionsmiddleware. This middleware is configured to retry a failed job up to 3 times, with a cooldown period of 5 minutes between attempts. Thebackoff(1)method ensures a delay of 1 minute before retrying. This setup is particularly useful for handling intermittent failures, such as temporary network issues or service unavailability.
- Exception Handling:
 The middleware checks for the specificHttpClientExceptionto apply the throttle only when this type of exception occurs. This ensures that only relevant errors are throttled, making the job handling more efficient and targeted.
- Job Execution:
 In thehandlemethod, the job attempts to fetch an article from a specified URL. If the server returns an error, the job is released back to the queue to be retried after 10 minutes. If successful, the response data is transformed and saved to the database.
- Controller and Route:
 TheArticleControllerincludes a method to handle incoming requests and dispatch theGetArticlejob. The route definition ensures that the controller method is accessible via a POST request.
Benefits of Using Middleware for HttpClientException
Using middleware specifically designed to handle HttpClientException in your jobs brings several targeted benefits:
- Targeted Error Handling:
 Middleware likeThrottlesExceptionscan be configured to handle specific exceptions such asHttpClientException. This means that only relevant HTTP client errors will trigger the retry mechanism, ensuring that your application doesn't waste resources retrying for non-recoverable errors.
- Retry Mechanism:
 By leveraging middleware, you can implement a robust retry mechanism. This allows your job to automatically retry a few times (e.g., up to 3 attempts) if it encounters anHttpClientException. This is particularly useful for dealing with transient network issues or temporary unavailability of external services.
- Cooldown Periods:
 The middleware can introduce cooldown periods (e.g., 5 minutes) between retries. This helps prevent hammering the external service with continuous requests, giving it time to recover if itβs experiencing issues.
- Customizable Backoff Strategies:
 You can customize the backoff strategy to wait a specific amount of time (e.g., 1 minute) before attempting the job again. This ensures that retries are spaced out, reducing the likelihood of repeated failures in quick succession.
- Improved Resilience:
 By automatically handling retries and managing failures, your job processing becomes more resilient. This helps maintain the smooth operation of your application even when external dependencies are unstable.
- Resource Optimization:
 Efficiently handling specific exceptions with middleware helps optimize server resources by avoiding unnecessary retries for non-recoverable errors. This keeps your queue workers focused on tasks that have a higher chance of success.
Conclusion
Integrating middleware into your Laravel job handling can significantly enhance the robustness and efficiency of your applications. The ThrottlesExceptions middleware, in particular, is a powerful tool for managing retries and handling specific exceptions like HttpClientException gracefully. By implementing such strategies, you ensure that your jobs are resilient and capable of dealing with intermittent failures effectively.
Found this helpful?
If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!