Skip to content

Commit

Permalink
fix: handle invalid Intl formats with intl.use_exceptions=1
Browse files Browse the repository at this point in the history
If `intl.use_exceptions=1`, ext/intl will throw an `\IntlException` that
was not yet handled and caused `StringFormatter::format()` to violate
its contract to throw `StringFormatterError` in case of errors.
  • Loading branch information
TimWolla committed Aug 22, 2023
1 parent 8d0d812 commit 29da9ac
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
14 changes: 12 additions & 2 deletions src/Utility/String/StringFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace CuyZ\Valinor\Utility\String;

use CuyZ\Valinor\Mapper\Tree\Message\HasParameters;
use IntlException;
use MessageFormatter;

use function class_exists;
Expand Down Expand Up @@ -37,8 +38,17 @@ public static function for(HasParameters $message): string
*/
private static function formatWithIntl(string $locale, string $body, array $parameters): string
{
return MessageFormatter::formatMessage($locale, $body, $parameters)
?: throw new StringFormatterError($body, intl_get_error_message());
try {
$formatted = MessageFormatter::formatMessage($locale, $body, $parameters);

if ($formatted === false) {
throw new StringFormatterError($body, intl_get_error_message());
}

return $formatted;
} catch (IntlException $e) {
throw new StringFormatterError($body, $e->getMessage(), $e);
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Utility/String/StringFormatterError.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
/** @internal */
final class StringFormatterError extends RuntimeException
{
public function __construct(string $body, string $message = '')
public function __construct(string $body, string $message = '', ?\Throwable $previous = null)
{
if ($message !== '') {
$message = ": $message";
}
parent::__construct("Message formatter error using `$body`$message.", 1652901203);
parent::__construct("Message formatter error using `$body`$message.", 1652901203, $previous);
}
}
18 changes: 18 additions & 0 deletions tests/Unit/Utility/String/StringFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ public function test_wrong_intl_format_throws_exception(): void
StringFormatter::format('en', 'some {wrong.format}', []);
}

/**
* @requires extension intl
*/
public function test_wrong_intl_format_throws_exception_with_intl_exception(): void
{
$oldIni = ini_get('intl.use_exceptions');
try {
ini_set('intl.use_exceptions', '1');
$this->expectException(StringFormatterError::class);
$this->expectExceptionMessage('Message formatter error using `some {wrong.format}`');
$this->expectExceptionCode(1652901203);

StringFormatter::format('en', 'some {wrong.format}', []);
} finally {
ini_set('intl.use_exceptions', $oldIni);
}
}

public function test_wrong_message_body_format_throws_exception(): void
{
$this->expectException(StringFormatterError::class);
Expand Down

0 comments on commit 29da9ac

Please sign in to comment.