@@ -115,7 +115,7 @@ function mergeFiles(string ...$files): string
115115 $taskGroup->spawn(file_get_contents(...), $file);
116116 }
117117
118- return array_merge("\n", await $taskGroup);
118+ return array_merge("\n", await $taskGroup->all() );
119119}
120120```
121121
@@ -2170,6 +2170,83 @@ The `getErrors()` method will return an array of exceptions.
21702170
21712171The ` TaskGroup ` class allows you to cancel all tasks in the group using the ` cancel() ` method.
21722172
2173+ This method behaves the same way as ` TaskGroup::dispose ` ,
2174+ with the only difference being that it allows you to pass a specific exception.
2175+
2176+ ``` php
2177+ use Async\TaskGroup;
2178+
2179+ $taskGroup = new Async\TaskGroup(captureResults: false);
2180+ $taskGroup->add(spawn {
2181+ try {
2182+ suspend;
2183+ } catch (Throwable $throwable) {
2184+ echo "Task was cancelled: ", $throwable->getMessage(), "\n";
2185+ }
2186+ });
2187+
2188+ // pass control to the task
2189+ suspend;
2190+
2191+ $taskGroup->cancel(new \Async\CancellationException('Custom cancellation message'));
2192+ ```
2193+
2194+ ** Expected output:**
2195+
2196+ ```
2197+ Task was cancelled: Custom cancellation message
2198+ ```
2199+
2200+ #### TaskGroup error handling
2201+
2202+ ` TaskGroup ` does not introduce additional logic for handling coroutine exceptions.
2203+ When a developer uses the expression ` await $taskGroup ` , they are capturing the exceptions
2204+ of all tasks contained within ` $taskGroup ` .
2205+ In other words, ` await $taskGroup ` is equivalent to simultaneously using ` await $coroutine ` for each task.
2206+ If no one awaits ` $taskGroup ` , the exception handling follows the general ` Flow ` ,
2207+ and the error will propagate to the ` Scope ` .
2208+
2209+ An additional method ` TaskGroup::all(bool $ignoreErrors = false, $nullOnFail = false): Awaitable {} ` provides a trigger
2210+ that fires when all tasks in the group have completed.
2211+ At the same time, it captures any errors, which can be retrieved using ` TaskGroup::getErrors() ` .
2212+
2213+ ``` php
2214+ // Returns an array of all tasks with their results ignoring errors
2215+ return $taskGroup->all(ignoreErrors: true);
2216+ ```
2217+
2218+ The trigger ` TaskGroup::all() ` returns an array of results with numeric indices,
2219+ where each index corresponds to the ordinal number of the task.
2220+ If a task completed with an error, its numeric index will be missing from the array.
2221+
2222+ Using the option ` $nullOnFail ` , you can specify that the results of failed
2223+ tasks should be filled with ` NULL ` instead.
2224+
2225+ ``` php
2226+ $taskGroup = new Async\TaskGroup(captureResults: true);
2227+ $taskGroup->add(spawn {return 'result 1';});
2228+ $taskGroup->add(spawn {throw new Exception('Error')});
2229+
2230+ var_dump(await $taskGroup->all(ignoreErrors: true, nullOnFail: true));
2231+ ```
2232+
2233+ ** Expected output:**
2234+
2235+ ``` php
2236+ array(2) {
2237+ [0]=>
2238+ string(8) "result 1"
2239+ [1]=>
2240+ NULL
2241+ }
2242+ ```
2243+
2244+ The method ` TaskGroup::getErrors() ` returns an array with numeric indices and exceptions,
2245+ where each index corresponds to the ordinal number of the task.
2246+
2247+ > ** Note:** The method ` TaskGroup::disposeResults ` clears all results and errors at the moment it is called.
2248+ > Coroutines then reset their ordinal indices starting from zero.
2249+
21732250### Context
21742251
21752252#### Motivation
0 commit comments