Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/Exception/Failure/ApplicationErrorCategory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/**
* This file is part of Temporal package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Temporal\Exception\Failure;

/**
* Used to categorize application failures, for example, to distinguish benign errors from others.
*
* @see \Temporal\Api\Enums\V1\ApplicationErrorCategory
*/
enum ApplicationErrorCategory: int
{
case Unspecified = 0;

/**
* Expected application error with little/no severity.
*/
case Benign = 1;
}
7 changes: 7 additions & 0 deletions src/Exception/Failure/ApplicationFailure.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class ApplicationFailure extends TemporalFailure
/**
* @param ValuesInterface|null $details Optional details about the failure.
* @param \DateInterval|null $nextRetryDelay Delay before the next retry attempt.
* @param ApplicationErrorCategory $category The category of the application failure.
*/
public function __construct(
string $message,
Expand All @@ -57,6 +58,7 @@ public function __construct(
?ValuesInterface $details = null,
?\Throwable $previous = null,
private ?\DateInterval $nextRetryDelay = null,
private readonly ApplicationErrorCategory $category = ApplicationErrorCategory::Unspecified,
) {
parent::__construct(
self::buildMessage(\compact('message', 'type', 'nonRetryable')),
Expand Down Expand Up @@ -103,4 +105,9 @@ public function setNextRetryDelay(?\DateInterval $nextRetryDelay): void
{
$this->nextRetryDelay = $nextRetryDelay;
}

public function getApplicationErrorCategory(): ApplicationErrorCategory
{
return $this->category;
}
}
2 changes: 2 additions & 0 deletions src/Exception/Failure/FailureConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public static function mapExceptionToFailure(\Throwable $e, DataConverterInterfa
$info = new ApplicationFailureInfo();
$info->setType($e->getType());
$info->setNonRetryable($e->isNonRetryable());
$info->setCategory($e->getApplicationErrorCategory()->value);

// Set Next Retry Delay
$nextRetry = DateInterval::toDuration($e->getNextRetryDelay());
Expand Down Expand Up @@ -181,6 +182,7 @@ private static function createFailureException(Failure $failure, DataConverterIn
$details,
$previous,
DateInterval::parseOrNull($info->getNextRetryDelay()),
ApplicationErrorCategory::tryFrom($info->getCategory()) ?? ApplicationErrorCategory::Unspecified,
);

case $failure->hasTimeoutFailureInfo():
Expand Down
19 changes: 19 additions & 0 deletions tests/Unit/Exception/FailureConverterTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Temporal\Api\Failure\V1\Failure;
use Temporal\DataConverter\DataConverter;
use Temporal\DataConverter\EncodedValues;
use Temporal\Exception\Failure\ApplicationErrorCategory;
use Temporal\Exception\Failure\ApplicationFailure;
use Temporal\Exception\Failure\FailureConverter;
use Temporal\Tests\Unit\AbstractUnit;
Expand Down Expand Up @@ -178,5 +179,23 @@ public function testMapExceptionToFailure(): void
$this->assertTrue($failure->getApplicationFailureInfo()->getNonRetryable());
$this->assertEmpty($failure->getApplicationFailureInfo()->getDetails());
$this->assertNull($failure->getApplicationFailureInfo()->getNextRetryDelay());
$this->assertSame(0, $failure->getApplicationFailureInfo()->getCategory());
}

public function testMapAppFailureWithCategory(): void
{
$converter = DataConverter::createDefault();
$exception = new ApplicationFailure(
'message',
'type',
true,
category: ApplicationErrorCategory::Benign,
);

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

self::assertInstanceOf(ApplicationFailure::class, $newException);
$this->assertSame(ApplicationErrorCategory::Benign, $newException->getApplicationErrorCategory());
}
}
Loading