Skip to content

Commit

Permalink
ApplicationFailure: add nextRetryDelay field with its mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Sep 24, 2024
1 parent ca8036f commit bfacaf4
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
14 changes: 13 additions & 1 deletion src/Exception/Failure/ApplicationFailure.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,17 @@ class ApplicationFailure extends TemporalFailure
* @param string $message
* @param string $type
* @param bool $nonRetryable
* @param ValuesInterface|null $details
* @param ValuesInterface|null $details Optional details about the failure.
* @param \Throwable|null $previous
* @param \DateInterval|null $nextRetryDelay Delay before the next retry attempt.
*/
public function __construct(
string $message,
string $type,
bool $nonRetryable,
ValuesInterface $details = null,
\Throwable $previous = null,
private ?\DateInterval $nextRetryDelay = null,
) {
parent::__construct(
self::buildMessage(\compact('message', 'type', 'nonRetryable')),
Expand Down Expand Up @@ -87,6 +89,11 @@ public function getDetails(): ValuesInterface
return $this->details;
}

public function getNextRetryDelay(): ?\DateInterval
{
return $this->nextRetryDelay;
}

/**
* @return bool
*/
Expand All @@ -110,4 +117,9 @@ public function setDataConverter(DataConverterInterface $converter): void
{
$this->details->setDataConverter($converter);
}

public function setNextRetryDelay(?\DateInterval $nextRetryDelay): void
{
$this->nextRetryDelay = $nextRetryDelay;
}
}
15 changes: 11 additions & 4 deletions src/Exception/Failure/FailureConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use Temporal\DataConverter\DataConverterInterface;
use Temporal\DataConverter\EncodedValues;
use Temporal\Exception\Client\ActivityCanceledException;
use Temporal\Internal\Support\DateInterval;

final class FailureConverter
{
Expand Down Expand Up @@ -192,22 +193,24 @@ private static function createFailureException(Failure $failure, DataConverterIn
switch (true) {
case $failure->hasApplicationFailureInfo():
$info = $failure->getApplicationFailureInfo();
\assert($info instanceof ApplicationFailureInfo);

$details = $info->hasDetails()
? EncodedValues::fromPayloads($info->getDetails(), $converter)
: EncodedValues::empty()
;
: EncodedValues::empty();

return new ApplicationFailure(
$failure->getMessage(),
$info->getType(),
$info->getNonRetryable(),
$details,
$previous,
DateInterval::parseOrNull($info->getNextRetryDelay()),
);

case $failure->hasTimeoutFailureInfo():
$info = $failure->getTimeoutFailureInfo();
\assert($info instanceof TimeoutFailureInfo);

$details = $info->hasLastHeartbeatDetails()
? EncodedValues::fromPayloads($info->getLastHeartbeatDetails(), $converter)
Expand All @@ -218,6 +221,7 @@ private static function createFailureException(Failure $failure, DataConverterIn

case $failure->hasCanceledFailureInfo():
$info = $failure->getCanceledFailureInfo();
\assert($info instanceof CanceledFailureInfo);

$details = $info->hasDetails()
? EncodedValues::fromPayloads($info->getDetails(), $converter)
Expand All @@ -231,14 +235,14 @@ private static function createFailureException(Failure $failure, DataConverterIn

case $failure->hasServerFailureInfo():
$info = $failure->getServerFailureInfo();
\assert($info instanceof ServerFailureInfo);
return new ServerFailure($failure->getMessage(), $info->getNonRetryable(), $previous);

case $failure->hasResetWorkflowFailureInfo():
$info = $failure->getResetWorkflowFailureInfo();
$details = $info->hasLastHeartbeatDetails()
? EncodedValues::fromPayloads($info->getLastHeartbeatDetails(), $converter)
: EncodedValues::empty()
;
: EncodedValues::empty();

return new ApplicationFailure(
$failure->getMessage(),
Expand All @@ -250,6 +254,7 @@ private static function createFailureException(Failure $failure, DataConverterIn

case $failure->hasActivityFailureInfo():
$info = $failure->getActivityFailureInfo();
\assert($info instanceof ActivityFailureInfo);

return new ActivityFailure(
$info->getScheduledEventId(),
Expand All @@ -264,6 +269,8 @@ private static function createFailureException(Failure $failure, DataConverterIn
case $failure->hasChildWorkflowExecutionFailureInfo():
$info = $failure->getChildWorkflowExecutionFailureInfo();
$execution = $info->getWorkflowExecution();
\assert($info instanceof ChildWorkflowExecutionFailureInfo);

Check failure on line 272 in src/Exception/Failure/FailureConverter.php

View workflow job for this annotation

GitHub Actions / Psalm Validation (PHP 8.3, OS ubuntu-latest)

RedundantCondition

src/Exception/Failure/FailureConverter.php:272:17: RedundantCondition: Type Temporal\Api\Failure\V1\ChildWorkflowExecutionFailureInfo for $info is always Temporal\Api\Failure\V1\ChildWorkflowExecutionFailureInfo (see https://psalm.dev/122)
\assert($execution instanceof WorkflowExecution);

return new ChildWorkflowFailure(
$info->getInitiatedEventId(),
Expand Down
3 changes: 2 additions & 1 deletion src/Exception/Failure/TemporalFailure.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public function setOriginalStackTrace(string $stackTrace): void
}

/**
* @return bool
* @psalm-assert-if-true non-empty-string $this->originalStackTrace
* @psalm-assert-if-false null $this->originalStackTrace
*/
public function hasOriginalStackTrace(): bool
{
Expand Down
32 changes: 30 additions & 2 deletions tests/Unit/Exception/FailureConverterTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
namespace Temporal\Tests\Unit\Exception;

use Exception;
use Google\Protobuf\Duration;
use Temporal\DataConverter\DataConverter;
use Temporal\DataConverter\EncodedCollection;
use Temporal\DataConverter\EncodedValues;
use Temporal\Exception\Failure\ApplicationFailure;
use Temporal\Exception\Failure\FailureConverter;
use Temporal\Internal\Support\DateInterval;
use Temporal\Tests\Unit\AbstractUnit;

final class FailureConverterTestCase extends AbstractUnit
Expand All @@ -19,13 +22,13 @@ public function testApplicationFailureCanTransferData(): void
'message',
'type',
true,
EncodedValues::fromValues(['abc', 123])
EncodedValues::fromValues(['abc', 123]),
);

$failure = FailureConverter::mapExceptionToFailure($exception, DataConverter::createDefault());
$restoredDetails = EncodedValues::fromPayloads(
$failure->getApplicationFailureInfo()->getDetails(),
DataConverter::createDefault()
DataConverter::createDefault(),
);

$this->assertSame('abc', $restoredDetails->getValue(0));
Expand Down Expand Up @@ -104,4 +107,29 @@ public function testStackTraceStringWithoutExceptionArgs(): void
$trace,
);
}

public function testMapFailureToException(): void
{
$converter = DataConverter::createDefault();
$failure = new \Temporal\Api\Failure\V1\Failure();
$failure->setApplicationFailureInfo($info = new \Temporal\Api\Failure\V1\ApplicationFailureInfo());
$failure->setStackTrace("test stack trace:\n#1\n#2\n#3");
// Populate the info
$info->setType('testType');
$info->setDetails(EncodedValues::fromValues(['foo', 'bar'], $converter)->toPayloads());
$info->setNonRetryable(true);
$info->setNextRetryDelay((new Duration())->setSeconds(13)->setNanos(15_000));

$exception = FailureConverter::mapFailureToException($failure, $converter);

$this->assertInstanceOf(ApplicationFailure::class, $exception);
$this->assertSame('testType', $exception->getType());
$this->assertTrue($exception->isNonRetryable());
$this->assertSame(['foo', 'bar'], $exception->getDetails()->getValues());
// Next retry delay
$this->assertSame(13, $exception->getNextRetryDelay()->seconds);
$this->assertSame(15, $exception->getNextRetryDelay()->microseconds);
$this->assertTrue($exception->hasOriginalStackTrace());
$this->assertSame("test stack trace:\n#1\n#2\n#3", $exception->getOriginalStackTrace());
}
}

0 comments on commit bfacaf4

Please sign in to comment.