Skip to content

Commit 7f0cab1

Browse files
committed
fix: Language does not throw exception
We have code like this: throw PageNotFoundException::forMethodNotFound($this->method); and public static function forMethodNotFound(string $method) { return new static(self::lang('HTTP.methodNotFound', [$method])); } If Language throws an Exception, the first Exception will be hidden in the error message.
1 parent 4a58d24 commit 7f0cab1

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

system/Language/Language.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace CodeIgniter\Language;
1313

1414
use Config\Services;
15-
use InvalidArgumentException;
15+
use IntlException;
1616
use MessageFormatter;
1717

1818
/**
@@ -194,9 +194,26 @@ protected function formatMessage($message, array $args = [])
194194

195195
$formatted = MessageFormatter::formatMessage($this->locale, $message, $args);
196196
if ($formatted === false) {
197-
throw new InvalidArgumentException(
198-
lang('Language.invalidMessageFormat', [$message, implode(',', $args)])
197+
// Format again to get the error message.
198+
try {
199+
$fmt = new MessageFormatter($this->locale, $message);
200+
$formatted = $fmt->format($args);
201+
$fmtError = '"' . $fmt->getErrorMessage() . '" (' . $fmt->getErrorCode() . ')';
202+
} catch (IntlException $e) {
203+
$fmtError = '"' . $e->getMessage() . '" (' . $e->getCode() . ')';
204+
}
205+
206+
$argsString = implode(',', $args);
207+
208+
log_message(
209+
'error',
210+
'Language.invalidMessageFormat: $message: "' . $message
211+
. '", $args: "' . $argsString . '"'
212+
. ' (urlencoded: ' . rawurlencode($argsString) . '),'
213+
. ' MessageFormatter Error: ' . $fmtError
199214
);
215+
216+
return $message . "\n【Warning】Also, invalid string(s) was passed to the Language class. See log file for details.";
200217
}
201218

202219
return $formatted;

tests/system/Language/LanguageTest.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use CodeIgniter\Test\CIUnitTestCase;
1515
use CodeIgniter\Test\Mock\MockLanguage;
1616
use Config\Services;
17-
use InvalidArgumentException;
1817
use MessageFormatter;
1918
use Tests\Support\Language\SecondMockLanguage;
2019

@@ -137,18 +136,14 @@ public function testGetLineInvalidFormatMessage(): void
137136
$this->markTestSkipped('No intl support.');
138137
}
139138

140-
$this->expectException(InvalidArgumentException::class);
141-
$this->expectExceptionMessage(
142-
'Invalid message format: "تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.", args: "password,hits,wording"'
143-
);
144-
145139
$this->lang->setLocale('ar');
146140

147-
$this->lang->setData('Auth', [
148-
'errorPasswordPwned' => 'تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.',
149-
]);
141+
$line = 'تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.';
142+
$this->lang->setData('Auth', ['errorPasswordPwned' => $line]);
143+
144+
$output = $this->lang->getLine('Auth.errorPasswordPwned', ['password', 'hits', 'wording']);
150145

151-
$this->lang->getLine('Auth.errorPasswordPwned', ['password', 'hits', 'wording']);
146+
$this->assertSame($line . "\n【Warning】Also, invalid string(s) was passed to the Language class. See log file for details.", $output);
152147
}
153148

154149
/**

0 commit comments

Comments
 (0)