mirror of
https://github.com/danog/parallel.git
synced 2024-11-26 20:34:40 +01:00
Improve error messages when unserializable data is used
This commit is contained in:
parent
3c0baa4e43
commit
14def89bff
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Amp\Parallel\Worker\Internal;
|
||||
|
||||
use Amp\Failure;
|
||||
use Amp\Parallel\Worker\Task;
|
||||
use Amp\Promise;
|
||||
use Amp\Success;
|
||||
|
||||
@ -19,6 +21,13 @@ final class TaskSuccess extends TaskResult
|
||||
|
||||
public function promise(): Promise
|
||||
{
|
||||
if ($this->result instanceof \__PHP_Incomplete_Class) {
|
||||
return new Failure(new \Error(\sprintf(
|
||||
"Class instances returned from %s::run() must be autoloadable by the Composer autoloader",
|
||||
Task::class
|
||||
)));
|
||||
}
|
||||
|
||||
return new Success($this->result);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace Amp\Parallel\Worker;
|
||||
|
||||
use Amp\Coroutine;
|
||||
use Amp\Parallel\Sync\Channel;
|
||||
use Amp\Parallel\Sync\SerializationException;
|
||||
use Amp\Promise;
|
||||
use function Amp\call;
|
||||
|
||||
@ -50,7 +51,12 @@ final class TaskRunner
|
||||
|
||||
$job = null; // Free memory from last job.
|
||||
|
||||
yield $this->channel->send($result);
|
||||
try {
|
||||
yield $this->channel->send($result);
|
||||
} catch (SerializationException $exception) {
|
||||
// Could not serialize task result.
|
||||
yield $this->channel->send(new Internal\TaskFailure($result->getId(), $exception));
|
||||
}
|
||||
|
||||
$result = null; // Free memory from last result.
|
||||
|
||||
|
@ -7,6 +7,7 @@ use Amp\Parallel\Sync\SerializationException;
|
||||
use Amp\Parallel\Worker\Environment;
|
||||
use Amp\Parallel\Worker\Task;
|
||||
use Amp\Parallel\Worker\TaskError;
|
||||
use Amp\Parallel\Worker\TaskException;
|
||||
use Amp\Parallel\Worker\WorkerException;
|
||||
use Amp\PHPUnit\TestCase;
|
||||
|
||||
@ -203,7 +204,7 @@ abstract class AbstractWorkerTest extends TestCase
|
||||
{
|
||||
}
|
||||
});
|
||||
$this->fail("Tasks that cannot be autoloaded should throw an exception");
|
||||
$this->fail("Tasks that cannot be serialized should throw an exception");
|
||||
} catch (SerializationException $exception) {
|
||||
$this->assertSame(0, \strpos($exception->getMessage(), "The given data cannot be sent because it is not serializable"));
|
||||
}
|
||||
@ -212,6 +213,38 @@ abstract class AbstractWorkerTest extends TestCase
|
||||
});
|
||||
}
|
||||
|
||||
public function testUnserializableResult()
|
||||
{
|
||||
Loop::run(function () {
|
||||
$worker = $this->createWorker();
|
||||
|
||||
try {
|
||||
yield $worker->enqueue(new UnserializableResultTask);
|
||||
$this->fail("Tasks results that cannot be serialized should throw an exception");
|
||||
} catch (TaskException $exception) {
|
||||
$this->assertSame(0, \strpos($exception->getMessage(), "Uncaught Amp\Parallel\Sync\SerializationException in worker"));
|
||||
}
|
||||
|
||||
yield $worker->shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
public function testNonAutoloadableResult()
|
||||
{
|
||||
Loop::run(function () {
|
||||
$worker = $this->createWorker();
|
||||
|
||||
try {
|
||||
yield $worker->enqueue(new NonAutoloadableResultTask);
|
||||
$this->fail("Tasks results that cannot be autoloaded should throw an exception");
|
||||
} catch (\Error $exception) {
|
||||
$this->assertSame(0, \strpos($exception->getMessage(), "Class instances returned from Amp\Parallel\Worker\Task::run() must be autoloadable by the Composer autoloader"));
|
||||
}
|
||||
|
||||
yield $worker->shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
public function testUnserializableTaskFollowedByValidTask()
|
||||
{
|
||||
Loop::run(function () {
|
||||
|
15
test/Worker/NonAutoloadableResultTask.php
Normal file
15
test/Worker/NonAutoloadableResultTask.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Amp\Parallel\Test\Worker;
|
||||
|
||||
use Amp\Parallel\Worker\Environment;
|
||||
use Amp\Parallel\Worker\Task;
|
||||
|
||||
class NonAutoloadableResultTask implements Task
|
||||
{
|
||||
public function run(Environment $environment)
|
||||
{
|
||||
require __DIR__ . "/non-autoloadable-class.php";
|
||||
return new NonAutoloadableClass;
|
||||
}
|
||||
}
|
14
test/Worker/UnserializableResultTask.php
Normal file
14
test/Worker/UnserializableResultTask.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Amp\Parallel\Test\Worker;
|
||||
|
||||
use Amp\Parallel\Worker\Environment;
|
||||
use Amp\Parallel\Worker\Task;
|
||||
|
||||
class UnserializableResultTask implements Task
|
||||
{
|
||||
public function run(Environment $environment)
|
||||
{
|
||||
return function () {}; // Anonymous functions are not serializable.
|
||||
}
|
||||
}
|
7
test/Worker/non-autoloadable-class.php
Normal file
7
test/Worker/non-autoloadable-class.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Amp\Parallel\Test\Worker;
|
||||
|
||||
class NonAutoloadableClass
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user