Skip to content

Commit 89e9046

Browse files
committed
Try to apply the custom error handler strategy to special cases
1 parent 7fd5813 commit 89e9046

File tree

5 files changed

+307
-51
lines changed

5 files changed

+307
-51
lines changed

lib/DateTime.php

+48-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,20 @@ private static function createFromRegular(\DateTime $datetime): self
2424
*/
2525
public static function createFromFormat($format, $time, $timezone = null): self
2626
{
27+
$error = [];
28+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
29+
$error = [
30+
'type' => $errno,
31+
'message' => $errstr,
32+
'file' => $errfile,
33+
'line' => $errline,
34+
];
35+
return false;
36+
});
2737
$datetime = \DateTime::createFromFormat($format, $time, $timezone);
38+
restore_error_handler();
2839
if ($datetime === false) {
29-
throw DatetimeException::createFromPhpError();
40+
throw DatetimeException::createFromPhpError($error);
3041
}
3142
return self::createFromRegular($datetime);
3243
}
@@ -39,10 +50,21 @@ public static function createFromFormat($format, $time, $timezone = null): self
3950
*/
4051
public function diff($datetime2, $absolute = false): DateInterval
4152
{
53+
$error = [];
54+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
55+
$error = [
56+
'type' => $errno,
57+
'message' => $errstr,
58+
'file' => $errfile,
59+
'line' => $errline,
60+
];
61+
return false;
62+
});
4263
/** @var \DateInterval|false $result */
4364
$result = parent::diff($datetime2, $absolute);
65+
restore_error_handler();
4466
if ($result === false) {
45-
throw DatetimeException::createFromPhpError();
67+
throw DatetimeException::createFromPhpError($error);
4668
}
4769
return $result;
4870
}
@@ -54,10 +76,21 @@ public function diff($datetime2, $absolute = false): DateInterval
5476
*/
5577
public function modify($modify): self
5678
{
79+
$error = [];
80+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
81+
$error = [
82+
'type' => $errno,
83+
'message' => $errstr,
84+
'file' => $errfile,
85+
'line' => $errline,
86+
];
87+
return false;
88+
});
5789
/** @var DateTime|false $result */
5890
$result = parent::modify($modify);
91+
restore_error_handler();
5992
if ($result === false) {
60-
throw DatetimeException::createFromPhpError();
93+
throw DatetimeException::createFromPhpError($error);
6194
}
6295
return $result;
6396
}
@@ -71,10 +104,21 @@ public function modify($modify): self
71104
*/
72105
public function setDate($year, $month, $day): self
73106
{
107+
$error = [];
108+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
109+
$error = [
110+
'type' => $errno,
111+
'message' => $errstr,
112+
'file' => $errfile,
113+
'line' => $errline,
114+
];
115+
return false;
116+
});
74117
/** @var DateTime|false $result */
75118
$result = parent::setDate($year, $month, $day);
119+
restore_error_handler();
76120
if ($result === false) {
77-
throw DatetimeException::createFromPhpError();
121+
throw DatetimeException::createFromPhpError($error);
78122
}
79123
return $result;
80124
}

lib/DateTimeImmutable.php

+132-11
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,20 @@ public function getInnerDateTime(): \DateTimeImmutable
5353
*/
5454
public static function createFromFormat($format, $time, $timezone = null): self
5555
{
56+
$error = [];
57+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
58+
$error = [
59+
'type' => $errno,
60+
'message' => $errstr,
61+
'file' => $errfile,
62+
'line' => $errline,
63+
];
64+
return false;
65+
});
5666
$datetime = \DateTimeImmutable::createFromFormat($format, $time, $timezone);
67+
restore_error_handler();
5768
if ($datetime === false) {
58-
throw DatetimeException::createFromPhpError();
69+
throw DatetimeException::createFromPhpError($error);
5970
}
6071
return self::createFromRegular($datetime);
6172
}
@@ -67,10 +78,21 @@ public static function createFromFormat($format, $time, $timezone = null): self
6778
*/
6879
public function format($format): string
6980
{
81+
$error = [];
82+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
83+
$error = [
84+
'type' => $errno,
85+
'message' => $errstr,
86+
'file' => $errfile,
87+
'line' => $errline,
88+
];
89+
return false;
90+
});
7091
/** @var string|false $result */
7192
$result = $this->innerDateTime->format($format);
93+
restore_error_handler();
7294
if ($result === false) {
73-
throw DatetimeException::createFromPhpError();
95+
throw DatetimeException::createFromPhpError($error);
7496
}
7597
return $result;
7698
}
@@ -83,10 +105,21 @@ public function format($format): string
83105
*/
84106
public function diff($datetime2, $absolute = false): \DateInterval
85107
{
108+
$error = [];
109+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
110+
$error = [
111+
'type' => $errno,
112+
'message' => $errstr,
113+
'file' => $errfile,
114+
'line' => $errline,
115+
];
116+
return false;
117+
});
86118
/** @var \DateInterval|false $result */
87119
$result = $this->innerDateTime->diff($datetime2, $absolute);
120+
restore_error_handler();
88121
if ($result === false) {
89-
throw DatetimeException::createFromPhpError();
122+
throw DatetimeException::createFromPhpError($error);
90123
}
91124
return $result;
92125
}
@@ -98,10 +131,21 @@ public function diff($datetime2, $absolute = false): \DateInterval
98131
*/
99132
public function modify($modify): self
100133
{
134+
$error = [];
135+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
136+
$error = [
137+
'type' => $errno,
138+
'message' => $errstr,
139+
'file' => $errfile,
140+
'line' => $errline,
141+
];
142+
return false;
143+
});
101144
/** @var \DateTimeImmutable|false $result */
102145
$result = $this->innerDateTime->modify($modify);
146+
restore_error_handler();
103147
if ($result === false) {
104-
throw DatetimeException::createFromPhpError();
148+
throw DatetimeException::createFromPhpError($error);
105149
}
106150
return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable
107151
}
@@ -115,10 +159,21 @@ public function modify($modify): self
115159
*/
116160
public function setDate($year, $month, $day): self
117161
{
162+
$error = [];
163+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
164+
$error = [
165+
'type' => $errno,
166+
'message' => $errstr,
167+
'file' => $errfile,
168+
'line' => $errline,
169+
];
170+
return false;
171+
});
118172
/** @var \DateTimeImmutable|false $result */
119173
$result = $this->innerDateTime->setDate($year, $month, $day);
174+
restore_error_handler();
120175
if ($result === false) {
121-
throw DatetimeException::createFromPhpError();
176+
throw DatetimeException::createFromPhpError($error);
122177
}
123178
return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable
124179
}
@@ -132,10 +187,21 @@ public function setDate($year, $month, $day): self
132187
*/
133188
public function setISODate($year, $week, $day = 1): self
134189
{
190+
$error = [];
191+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
192+
$error = [
193+
'type' => $errno,
194+
'message' => $errstr,
195+
'file' => $errfile,
196+
'line' => $errline,
197+
];
198+
return false;
199+
});
135200
/** @var \DateTimeImmutable|false $result */
136201
$result = $this->innerDateTime->setISODate($year, $week, $day);
202+
restore_error_handler();
137203
if ($result === false) {
138-
throw DatetimeException::createFromPhpError();
204+
throw DatetimeException::createFromPhpError($error);
139205
}
140206
return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable
141207
}
@@ -150,10 +216,21 @@ public function setISODate($year, $week, $day = 1): self
150216
*/
151217
public function setTime($hour, $minute, $second = 0, $microseconds = 0): self
152218
{
219+
$error = [];
220+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
221+
$error = [
222+
'type' => $errno,
223+
'message' => $errstr,
224+
'file' => $errfile,
225+
'line' => $errline,
226+
];
227+
return false;
228+
});
153229
/** @var \DateTimeImmutable|false $result */
154230
$result = $this->innerDateTime->setTime($hour, $minute, $second, $microseconds);
231+
restore_error_handler();
155232
if ($result === false) {
156-
throw DatetimeException::createFromPhpError();
233+
throw DatetimeException::createFromPhpError($error);
157234
}
158235
return self::createFromRegular($result);
159236
}
@@ -165,10 +242,21 @@ public function setTime($hour, $minute, $second = 0, $microseconds = 0): self
165242
*/
166243
public function setTimestamp($unixtimestamp): self
167244
{
245+
$error = [];
246+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
247+
$error = [
248+
'type' => $errno,
249+
'message' => $errstr,
250+
'file' => $errfile,
251+
'line' => $errline,
252+
];
253+
return false;
254+
});
168255
/** @var \DateTimeImmutable|false $result */
169256
$result = $this->innerDateTime->setTimestamp($unixtimestamp);
257+
restore_error_handler();
170258
if ($result === false) {
171-
throw DatetimeException::createFromPhpError();
259+
throw DatetimeException::createFromPhpError($error);
172260
}
173261
return self::createFromRegular($result);
174262
}
@@ -180,10 +268,21 @@ public function setTimestamp($unixtimestamp): self
180268
*/
181269
public function setTimezone($timezone): self
182270
{
271+
$error = [];
272+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
273+
$error = [
274+
'type' => $errno,
275+
'message' => $errstr,
276+
'file' => $errfile,
277+
'line' => $errline,
278+
];
279+
return false;
280+
});
183281
/** @var \DateTimeImmutable|false $result */
184282
$result = $this->innerDateTime->setTimezone($timezone);
283+
restore_error_handler();
185284
if ($result === false) {
186-
throw DatetimeException::createFromPhpError();
285+
throw DatetimeException::createFromPhpError($error);
187286
}
188287
return self::createFromRegular($result);
189288
}
@@ -195,10 +294,21 @@ public function setTimezone($timezone): self
195294
*/
196295
public function sub($interval): self
197296
{
297+
$error = [];
298+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
299+
$error = [
300+
'type' => $errno,
301+
'message' => $errstr,
302+
'file' => $errfile,
303+
'line' => $errline,
304+
];
305+
return false;
306+
});
198307
/** @var \DateTimeImmutable|false $result */
199308
$result = $this->innerDateTime->sub($interval);
309+
restore_error_handler();
200310
if ($result === false) {
201-
throw DatetimeException::createFromPhpError();
311+
throw DatetimeException::createFromPhpError($error);
202312
}
203313
return self::createFromRegular($result);
204314
}
@@ -208,10 +318,21 @@ public function sub($interval): self
208318
*/
209319
public function getOffset(): int
210320
{
321+
$error = [];
322+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use (&$error) {
323+
$error = [
324+
'type' => $errno,
325+
'message' => $errstr,
326+
'file' => $errfile,
327+
'line' => $errline,
328+
];
329+
return false;
330+
});
211331
/** @var int|false $result */
212332
$result = $this->innerDateTime->getOffset();
333+
restore_error_handler();
213334
if ($result === false) {
214-
throw DatetimeException::createFromPhpError();
335+
throw DatetimeException::createFromPhpError($error);
215336
}
216337
return $result;
217338
}

lib/Exceptions/PcreException.php

+1-10
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@ class PcreException extends \Exception implements SafeExceptionInterface
77
{
88
public static function createFromPhpError(): self
99
{
10-
$errorMap = [
11-
PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR: Internal error',
12-
PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR: Backtrack limit reached',
13-
PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR: Recursion limit reached',
14-
PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR: Invalid UTF8 character',
15-
PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR',
16-
PREG_JIT_STACKLIMIT_ERROR => 'PREG_JIT_STACKLIMIT_ERROR',
17-
];
18-
$errMsg = $errorMap[preg_last_error()] ?? 'Unknown PCRE error: '.preg_last_error();
19-
return new self($errMsg, \preg_last_error());
10+
return new self(\preg_last_error_msg(), \preg_last_error());
2011
}
2112
}

lib/Exceptions/SimplexmlException.php

+14-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@
33

44
class SimplexmlException extends \ErrorException implements SafeExceptionInterface
55
{
6-
public static function createFromPhpError(): self
6+
7+
/**
8+
*
9+
* @param array{type?: int, message?: string, file?: string, line?: int} $error
10+
* @return \Safe\Exceptions\SimplexmlException
11+
*/
12+
public static function createFromPhpError(array $error = []): self
713
{
8-
$error = \error_get_last();
9-
return new self($error['message'] ?? 'An error occured', 0, $error['type'] ?? 1);
14+
return new self(
15+
$error['message'] ?? 'An error occured',
16+
0,
17+
$error['type'] ?? 1,
18+
$error['file'] ?? __FILE__,
19+
$error['line'] ?? __LINE__,
20+
);
1021
}
1122
}

0 commit comments

Comments
 (0)