|
9 | 9 | use Exception; |
10 | 10 | use RuntimeException; |
11 | 11 | use Tests\TestCase; |
| 12 | +use Workflow\Serializers\Serializer; |
| 13 | +use Workflow\V2\Exceptions\RestoredWorkflowException; |
12 | 14 | use TypeError; |
13 | 15 | use Workflow\V2\Support\FailureFactory; |
14 | 16 |
|
@@ -68,4 +70,30 @@ public function testRestoresBaseException(): void |
68 | 70 | $this->assertInstanceOf(Exception::class, $restored); |
69 | 71 | $this->assertSame('base exception sanity check', $restored->getMessage()); |
70 | 72 | } |
| 73 | + |
| 74 | + public function testReplayPreservesStructuredFailureMetadata(): void |
| 75 | + { |
| 76 | + $payload = [ |
| 77 | + 'class' => RuntimeException::class, |
| 78 | + 'type' => 'planned.python.failure', |
| 79 | + 'message' => 'planned python failure', |
| 80 | + 'non_retryable' => true, |
| 81 | + 'details_payload_codec' => 'avro', |
| 82 | + 'details' => Serializer::serializeWithCodec('avro', ['label' => 'planned-python-failure']), |
| 83 | + ]; |
| 84 | + |
| 85 | + $restored = FailureFactory::restoreForReplay($payload); |
| 86 | + |
| 87 | + $this->assertInstanceOf(RestoredWorkflowException::class, $restored); |
| 88 | + $this->assertSame('planned python failure', $restored->getMessage()); |
| 89 | + $failurePayload = $restored->failurePayload(); |
| 90 | + |
| 91 | + $this->assertSame(RuntimeException::class, $failurePayload['class'] ?? null); |
| 92 | + $this->assertSame('planned.python.failure', $failurePayload['type'] ?? null); |
| 93 | + $this->assertSame('planned python failure', $failurePayload['message'] ?? null); |
| 94 | + $this->assertSame(0, $failurePayload['code'] ?? null); |
| 95 | + $this->assertTrue($failurePayload['non_retryable'] ?? false); |
| 96 | + $this->assertSame('avro', $failurePayload['details_payload_codec'] ?? null); |
| 97 | + $this->assertSame($payload['details'], $failurePayload['details'] ?? null); |
| 98 | + } |
71 | 99 | } |
0 commit comments