Conditionally Fail Queue Jobs While Throttling Exceptions in Laravel 12.20
Last updated on by Paul Redmond
Never Miss a Laravel Release 🚀
The Laravel team released v12.20.0 with the ability to fail while throttling queue exceptions, a Queue Facade fakeFor method, a Context::remember() method, the ability to customize Collection pluck() with a callback, and more:
Remember Context
Ben Askew contributed Context remember() and rememberHidden() functions, which will add the result of the provided closure function to the context if not already present, and always return the result:
// Beforeif (Context::has('user-permissions')) { $permissions = Context::get('user-permissions');} else { $permissions = auth()->user()->permissions; Context::set('user-permissions', $permissions);} // After$permissions = Context::remember('user-permissions', fn() => auth()->user()->permissions)
See Pull Request #56156 for details.
"Doesn't Start/End With" String Methods
Balboa Codes contributed doesntStartWith() and doesntEndWith() string methods to the Str and Stringable classes, which are the opposite of startsWith() and endsWith(). You can compare the value against another string or an array of strings:
use Illuminate\Support\Str; Str::doesntEndWith('This is my name', 'dog'); // trueStr::doesntEndWith('This is my name', ['name', 'foo']); // false Str::doesntStartWith('This is my name', 'That'); // trueStr::doesntStartWith('This is my name', ['This', 'That', 'There']); // false
See Pull Request #56168 for details. See the Strings documentation for more usage examples.
Add failWhen() Method to the ThrottlesExceptions Queue Middleware
Michael Dzjaparidze contributed a failWhen() method to the ThrottlesExceptions middleware:
Currently, this middleware only allows for deleting the job when a specific exception is thrown. There are occasions were you would want to mark the job as failed instead. For instance: in the context of a job chain it may be desirable to fail a job when an exception is thrown so that the chain stops executing.
Here's an example:
public function middleware(): array{ return [ (new ThrottlesExceptions(2, 10 * 60)) ->deleteWhen(CustomerDeletedException::class) ->failWhen(fn (\Throwable $e) => /* ... */) ];}
See Pull Request #56180 for details. Additionally, the Queues documentation provides more information on using the ThrottlesException middleware.
Add fakeFor() and fakeExceptFor() Methods to the Queue Facade
Punyapal Shah contributed new fake methods to the Queue facade that follow the same pattern used by the Event facade.
// Before: Fake affects the entire testQueue::fake();// ... test code ...// Manual cleanup required // After: Fake is automatically scopedQueue::fakeFor(function () { Queue::push(new ProcessPayment); Queue::assertPushed(ProcessPayment::class);}); // Original queue automatically restored // Selective job faking// Allow critical jobs to be queued normally, fake othersQueue::fakeExceptFor(function () { Queue::push(new CriticalSystemJob); // Actually queued Queue::push(new EmailNotification); // Faked Queue::assertNotPushed(CriticalSystemJob::class); Queue::assertPushed(EmailNotification::class);}, [CriticalSystemJob::class]);
See Pull Request #56149 for details.
Add JsonSerializable Interface to the Uri Class
@devajmeireles added the JsonSerializable interface to ensure the Uri class is converted property to JSON.
// GivenRoute::get('/testing', function () { return User::first()->only('id', 'url');}); /* Before {"id": 1, "url": {}} */ /* After {"id": 1, "url": "https://sanford.biz/..."} */
See Pull Request #56097 for details.
Make the Fluent class Iterable
Volodya Kurshudyan introduced the Iterable contract to the Fluent class, which addresses a small paper cut when using Fluent with loops:
// Need to call toArray() to iterateforeach ($user->settings->toArray() as $key => $value) { //} // Now, the `settings` property is iterable in Laravel 12.20foreach ($user->settings as $key => $value) { //}
See Pull Request #56218 for details.
Add collection() Method to the Config Repository
Kennedy Tedesco contributed a collection() method to return a collection instance from the Config repository:
// Beforecollect(Config::array('my_file.my_key')); // AfterConfig::collection('my_file.my_key');
See Pull Request #56200 for details.
Add Closure Support to the Collection pluck() Method
Ralph J. Smit contributed an update to the pluck() method to allow customizations to the keys and values returned:
This PR adds closure support to the
$key/$valueparameters of thepluck()methods. Very often I have that I almost can use pluck(), but I cannot because I need to make a slight modification to e.g. the key or value. I then need to solve this with mapWithKeys(), but that repeats the id and makes it way more verbose if you only just want to apply some formatting to the key and/or value.
After this PR, you can now do the following:
Country::get() ->pluck(fn (Country $country) => "{$country->flag} {$country->name}", 'id')
See Pull Request #56188 for details.
Context Blade Directive
Martin Bean contributed a @context Blade directive to determine if a context value exists:
@context('canonical') <link href="{{ $value }}" rel="canonical">@endcontext
See Pull Request #56146 for details.
Release notes
You can see the complete list of new features and updates below and the diff between 12.19.0 and 12.20.0 on GitHub. The following release notes are directly from the changelog:
v12.20.0
- [12.x] Pass TransportException to NotificationFailed event by @hackel in https://github.com/laravel/framework/pull/56061
- [12.x] use
offset()in place ofskip()by @browner12 in https://github.com/laravel/framework/pull/56081 - [12.x] use
limit()in place oftake()by @browner12 in https://github.com/laravel/framework/pull/56080 - [12.x] Display job queue names when running queue:work with --verbose option by @seriquynh in https://github.com/laravel/framework/pull/56086
- [12.x] use
offset()andlimit()in tests by @browner12 in https://github.com/laravel/framework/pull/56089 - [12.x] Localize “Pagination Navigation” aria-label by @andylolz in https://github.com/laravel/framework/pull/56103
- [12.x] Enhance the test coverage for Pipeline::through() by @azim-kordpour in https://github.com/laravel/framework/pull/56100
- [12.x] Added
JsonSerializableinterface toUriClass by @devajmeireles in https://github.com/laravel/framework/pull/56097 - [12.x] Display job connection name when running queue:work with --verbose option by @amirhshokri in https://github.com/laravel/framework/pull/56095
- [12.x] Fix PHPDoc for Arr::sole method by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56096
- [12.x] when a method returns
$thisset the return type tostaticby @browner12 in https://github.com/laravel/framework/pull/56092 - [12.x] Use
int<0, max>as docblock return type for database operations that return a count by @cosmastech in https://github.com/laravel/framework/pull/56117 - [12.x] Add missing @throws annotation to Number by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56116
- [12.x] Correct PHPDoc for Arr::sole callable type to avoid return type ambiguity by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56108
- Change return types of through (pagination) and transform (collection) by @glamorous in https://github.com/laravel/framework/pull/56105
- [12.x] Add maintenance mode facade for easier driver extension by @ziadoz in https://github.com/laravel/framework/pull/56090
- [12.x] Cache isSoftDeletable(), isPrunable(), and isMassPrunable() directly in model by @shaedrich in https://github.com/laravel/framework/pull/56078
- [12.x] Throws not throw by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56120
- [12.x] Fix @param docblock to allow string by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56121
- [11.x] Pass the limiter to the when & report callbacks by @jimmypuckett in https://github.com/laravel/framework/pull/56129
- [12.x] remove the "prefix" option for cache password resets by @browner12 in https://github.com/laravel/framework/pull/56127
- [12.x] Make Model::currentEncrypter public by @JaZo in https://github.com/laravel/framework/pull/56130
- [12.x] Add throws docblock by @amirhshokri in https://github.com/laravel/framework/pull/56137
- [12.x] Narrow integer range for
Collectionmethods by @cosmastech in https://github.com/laravel/framework/pull/56135 - [12.x] Allows using
--modeland--exceptviaPruneCommandcommand by @hosni in https://github.com/laravel/framework/pull/56140 - [12.x] Support Passing
HtmlableInstances toJs::from()by @jj15asmr in https://github.com/laravel/framework/pull/56159 - #56124 Properly escape column defaults by @asmecher in https://github.com/laravel/framework/pull/56158
- [12.x] Return early on belongs-to-many relationship
syncWithoutDetachingmethod when empty values are given by @stevebauman in https://github.com/laravel/framework/pull/56157 - [12.x] Add fakeFor and fakeExceptFor methods to Queue facade by @MrPunyapal in https://github.com/laravel/framework/pull/56149
- [11.x] Backport test fixes by @GrahamCampbell in https://github.com/laravel/framework/pull/56183
- Revert "[11.x] Pass the limiter to the when & report callbacks" by @GrahamCampbell in https://github.com/laravel/framework/pull/56184
- Add failWhen method to ThrottlesExceptions job middleware by @michaeldzjap in https://github.com/laravel/framework/pull/56180
- [12.x] Update Castable contract to accept string array by @hosmelq in https://github.com/laravel/framework/pull/56177
- Feature: doesntStartWith() and doesntEndWith() string methods by @balboacodes in https://github.com/laravel/framework/pull/56168
- [12.x] Add context remember functions by @btaskew in https://github.com/laravel/framework/pull/56156
- [12.x] Fix queue fake cleanup to always restore original queue manager by @xurshudyan in https://github.com/laravel/framework/pull/56165
- [12.x] Pass the limiter to the when & report callbacks by @GrahamCampbell in https://github.com/laravel/framework/pull/56187
- [12.x] Add
Closure-support to$key/$valuein Collectionpluck()method by @ralphjsmit in https://github.com/laravel/framework/pull/56188 - [12.x] Add
collection()to Config repository by @KennedyTedesco in https://github.com/laravel/framework/pull/56200 - Add int to allowed types of value in DatabaseRule by @vkarchevskyi in https://github.com/laravel/framework/pull/56199
- [12.x] Fix Event fake cleanup to always restore original event dispatcher by @xurshudyan in https://github.com/laravel/framework/pull/56189
- [12.x] Align PHPDoc style in Number::parseFloat with the rest of the class by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56206
- [12.x] Inconsistent use of @return type by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56207
- [12.x] Resolve issue with Factory make when automatic eager loading by @jackbayliss in https://github.com/laravel/framework/pull/56211
- [12.x] Refactor driver initialization using null coalescing assignment in Manager by @Ashot1995 in https://github.com/laravel/framework/pull/56210
- [12.x] Add URL signature macros to
Requestdocblock by @duncanmcclean in https://github.com/laravel/framework/pull/56230 - [12.x] Update PHPDoc for dataForSometimesIteration by @mrvipchien in https://github.com/laravel/framework/pull/56229
- [12.x] Avoid unnecessary filtering when no callback is provided by @AhmedAlaa4611 in https://github.com/laravel/framework/pull/56225
- [12.x] Make
Fluentclass iterable by @xurshudyan in https://github.com/laravel/framework/pull/56218 - Improve Mailable assertion error messages with expected vs actual values by @ahinkle in https://github.com/laravel/framework/pull/56221
- [12.x] Add
@​contextBlade directive by @martinbean in https://github.com/laravel/framework/pull/56146 - [12.x] fix: AsCommand properties not being set on commands by @calebdw in https://github.com/laravel/framework/pull/56235
- [12.x] Ensure
withLocaleandwithCurrencyalways restore previous state by @xurshudyan in https://github.com/laravel/framework/pull/56234