[php-src] Issue #9784: DateTime:: and DateTimeZone::__construct should throw a dedicated exception if the input is invalid
| From: | Daimona | Date: | Thu, 20 Oct 2022 12:56:44 +0000 |
| Subject: | [php-src] Issue #9784: DateTime:: and DateTimeZone::__construct should throw a dedicated exception if the input is invalid | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242646@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9784
Author: Daimona
### Description
If
DateTime::__construct or DateTimeZone::__construct receive invalid
input, they will throw a generic Exception ([3v4l for
DateTime](https://3v4l.org/M3u7H), [3v4l for DateTimeZone](https://3v4l.org/MUPlM)). This
contradicts the general principle that you should always use a dedicated exception type, and not the
generic Exception class. While it's less of a problem for PHP internal code,
things could still go wrong.
The main example is that you may be using a PHP extension that can throw exceptions while PHP
executes the constructor call. For instance, Wikimedia uses the
[Excimer](https://www.mediawiki.org/wiki/Excimer), which allows you to set interrupting timers, and
a dedicated exception (TimeoutException) is thrown as soon as the timer expires. In
practice, this means that whenever we want to instantiate a potentially invalid DateTime(Zone), the
code will look like this:
```php
try {
$x = new DateTimeZone( $somethingPotentiallyInvalid );
} catch ( TimeoutException $e ) {
throw $e;
} catch ( Exception $_ ) {
// Handle invalid time zone
}
```
This is not ideal, because you need to remember about TimeoutException possibly being thrown.
A dedicated exception would make it much more readable and straightforward, for instance:
```php
try {
$x = new DateTimeZone( $somethingPotentiallyInvalid );
} catch ( InvalidTimeZoneException $e ) {
// Handle invalid time zone
}
```
This change would also be backwards compatible, except for places (not too common, I guess) where
someone does things like:
```php
try {
$x = new DateTimeZone( $somethingPotentiallyInvalid );
} catch ( Exception $e ) {
if ( get_class( $e ) === Exception::class ) {
// ...
}
```