@@ -119,9 +119,7 @@ protected function ensureJobIsBatchable(object|array $job): void
119
119
*/
120
120
public function before ($ callback )
121
121
{
122
- $ this ->options ['before ' ][] = $ callback instanceof Closure
123
- ? new SerializableClosure ($ callback )
124
- : $ callback ;
122
+ $ this ->registerCallback ('before ' , $ callback );
125
123
126
124
return $ this ;
127
125
}
@@ -144,9 +142,7 @@ public function beforeCallbacks()
144
142
*/
145
143
public function progress ($ callback )
146
144
{
147
- $ this ->options ['progress ' ][] = $ callback instanceof Closure
148
- ? new SerializableClosure ($ callback )
149
- : $ callback ;
145
+ $ this ->registerCallback ('progress ' , $ callback );
150
146
151
147
return $ this ;
152
148
}
@@ -169,9 +165,7 @@ public function progressCallbacks()
169
165
*/
170
166
public function then ($ callback )
171
167
{
172
- $ this ->options ['then ' ][] = $ callback instanceof Closure
173
- ? new SerializableClosure ($ callback )
174
- : $ callback ;
168
+ $ this ->registerCallback ('then ' , $ callback );
175
169
176
170
return $ this ;
177
171
}
@@ -194,9 +188,7 @@ public function thenCallbacks()
194
188
*/
195
189
public function catch ($ callback )
196
190
{
197
- $ this ->options ['catch ' ][] = $ callback instanceof Closure
198
- ? new SerializableClosure ($ callback )
199
- : $ callback ;
191
+ $ this ->registerCallback ('catch ' , $ callback );
200
192
201
193
return $ this ;
202
194
}
@@ -219,9 +211,7 @@ public function catchCallbacks()
219
211
*/
220
212
public function finally ($ callback )
221
213
{
222
- $ this ->options ['finally ' ][] = $ callback instanceof Closure
223
- ? new SerializableClosure ($ callback )
224
- : $ callback ;
214
+ $ this ->registerCallback ('finally ' , $ callback );
225
215
226
216
return $ this ;
227
217
}
@@ -237,14 +227,31 @@ public function finallyCallbacks()
237
227
}
238
228
239
229
/**
240
- * Indicate that the batch should not be cancelled when a job within the batch fails.
230
+ * Indicate that the batch should not be canceled when a job within the batch fails;
231
+ * optionally add callbacks to be executed upon each job failure.
241
232
*
242
- * @param bool $allowFailures
243
- * @return $this
233
+ * When passed a boolean true, enables failure tolerance without callbacks.
234
+ * When passed a boolean false, disables failure tolerance.
235
+ * When passed callable(s), registers failure callbacks and enables failure tolerance.
236
+ * Invalid callables are silently ignored during registration.
237
+ *
238
+ * @template TParam of Closure(\Illuminate\Bus\Batch, \Throwable|null): mixed)|(callable(\Illuminate\Bus\Batch, \Throwable|null): mixed)
239
+ *
240
+ * @param bool|TParam|array<array-key, TParam> $param
244
241
*/
245
- public function allowFailures ($ allowFailures = true )
242
+ public function allowFailures (bool | Closure | callable | array $ param = true ): self
246
243
{
247
- $ this ->options ['allowFailures ' ] = $ allowFailures ;
244
+ if (! is_bool ($ param )) {
245
+ $ param = Arr::wrap ($ param );
246
+
247
+ foreach ($ param as $ callback ) {
248
+ if (is_callable ($ callback )) {
249
+ $ this ->registerCallback ('failure ' , $ callback );
250
+ }
251
+ }
252
+ }
253
+
254
+ $ this ->options ['allowFailures ' ] = ! ($ param === false );
248
255
249
256
return $ this ;
250
257
}
@@ -259,6 +266,26 @@ public function allowsFailures()
259
266
return Arr::get ($ this ->options , 'allowFailures ' , false ) === true ;
260
267
}
261
268
269
+ /**
270
+ * Get the "failure" callbacks that have been registered with the pending batch.
271
+ *
272
+ * @return array<array-key, Closure|callable>
273
+ */
274
+ public function failureCallbacks (): array
275
+ {
276
+ return $ this ->options ['failure ' ] ?? [];
277
+ }
278
+
279
+ /**
280
+ * Register a callback with proper serialization.
281
+ */
282
+ private function registerCallback (string $ type , Closure |callable $ callback ): void
283
+ {
284
+ $ this ->options [$ type ][] = $ callback instanceof Closure
285
+ ? new SerializableClosure ($ callback )
286
+ : $ callback ;
287
+ }
288
+
262
289
/**
263
290
* Set the name for the batch.
264
291
*
@@ -335,7 +362,7 @@ public function withOption(string $key, $value)
335
362
/**
336
363
* Dispatch the batch.
337
364
*
338
- * @return \Illuminate\Bus\ Batch
365
+ * @return Batch
339
366
*
340
367
* @throws \Throwable
341
368
*/
@@ -365,7 +392,7 @@ public function dispatch()
365
392
/**
366
393
* Dispatch the batch after the response is sent to the browser.
367
394
*
368
- * @return \Illuminate\Bus\ Batch
395
+ * @return Batch
369
396
*/
370
397
public function dispatchAfterResponse ()
371
398
{
@@ -385,7 +412,7 @@ public function dispatchAfterResponse()
385
412
/**
386
413
* Dispatch an existing batch.
387
414
*
388
- * @param \Illuminate\Bus\ Batch $batch
415
+ * @param Batch $batch
389
416
* @return void
390
417
*
391
418
* @throws \Throwable
@@ -409,7 +436,7 @@ protected function dispatchExistingBatch($batch)
409
436
* Dispatch the batch if the given truth test passes.
410
437
*
411
438
* @param bool|\Closure $boolean
412
- * @return \Illuminate\Bus\ Batch|null
439
+ * @return Batch|null
413
440
*/
414
441
public function dispatchIf ($ boolean )
415
442
{
@@ -420,7 +447,7 @@ public function dispatchIf($boolean)
420
447
* Dispatch the batch unless the given truth test passes.
421
448
*
422
449
* @param bool|\Closure $boolean
423
- * @return \Illuminate\Bus\ Batch|null
450
+ * @return Batch|null
424
451
*/
425
452
public function dispatchUnless ($ boolean )
426
453
{
@@ -431,7 +458,7 @@ public function dispatchUnless($boolean)
431
458
* Store the batch using the given repository.
432
459
*
433
460
* @param \Illuminate\Bus\BatchRepository $repository
434
- * @return \Illuminate\Bus\ Batch
461
+ * @return Batch
435
462
*/
436
463
protected function store ($ repository )
437
464
{
0 commit comments