@@ -229,6 +229,102 @@ happen with the agreement of the parties involved). This document does not try
229
229
to provide a hard guideline on what constitutes a sufficiently important
230
230
library. The application of common sense is recommended.
231
231
232
+ Throwables
233
+ ==========
234
+
235
+ Newly introduced extensions MUST follow the following rules, existing extensions
236
+ SHOULD follow the rules for newly introduced exceptions, but MAY diverge for
237
+ consistency with existing symbols.
238
+
239
+ In the interest of readability the following text uses the word "exception" to
240
+ refer to any kind of ``Throwable ``. ``Exception `` in code blocks refers to the
241
+ ``\Exception `` class.
242
+
243
+ The class name of an exception MUST end in ``Exception `` (when extending from
244
+ the ``Exception `` hierarchy) or ``Error `` (for the ``Error `` hierarchy).
245
+ Exceptions MUST NOT be ``final ``.
246
+
247
+ Extensions MUST have their own hierarchy of exceptions. At the lowest level of
248
+ the hierarchy there MUST be a base ``Exception `` and base ``Error `` defined
249
+ within the top-level of the extension's namespace. The unqualified class name of
250
+ the base exceptions must be the name of the extension followed by ``Exception ``
251
+ or ``Error ``. These base exceptions MUST directly extend from the global base
252
+ ``\Exception `` or ``\Error `` classes. The extension's base ``Error `` MAY be
253
+ omitted if it is unused.
254
+
255
+ As an example, an extension called ``Example `` would define the following base
256
+ exceptions:
257
+
258
+ .. code ::
259
+
260
+ namespace Example;
261
+
262
+ class ExampleException extends \Exception { }
263
+ class ExampleError extends \Error { }
264
+
265
+ An extension SHOULD define additional exceptions as appropriate to allow users
266
+ to catch specific classes of exception for granular error handling. Any
267
+ additional exception MUST either extend the extension's base exception or
268
+ another exception defined by the extension. The unqualified class name of
269
+ additional exceptions SHOULD be sufficiently specific to make collisions with
270
+ the unqualified class name of other exceptions unlikely. The name of the
271
+ extension SHOULD NOT be used within the unqualified class name of additional
272
+ exceptions if the only purpose is to make the class name more unique.
273
+ Specifically, the name of the extension SHOULD NOT be a simple prefix or suffix
274
+ of the unqualified class name.
275
+
276
+ As an example, an additional exception for failing HTTP requests of the curl
277
+ extension might be called ``Curl\FailedHttpRequestException ``. This is
278
+ sufficiently specific to avoid collisions, since using two different HTTP
279
+ clients in a single source file is unlikely. It should not use
280
+ ``Curl\CurlFailedHttpRequestException ``,
281
+ ``Curl\FailedCurlHttpRequestException ``,
282
+ ``Curl\FailedHttpRequestCurlException ``, or similar. A file extension however
283
+ might want to define a ``File\FileNotFoundException `` and a
284
+ ``File\DirectoryNotFoundException ``. In this case the name of the extension is a
285
+ generic term and the ``File `` prefix in ``FileNotFoundException `` adds useful
286
+ context to differentiate it from the ``DirectoryNotFoundException ``.
287
+
288
+ An extension MUST NOT throw exceptions that it did not define itself, except for
289
+ the global ``TypeError `` or ``ValueError `` exceptions thrown during parameter
290
+ parsing and parameter validation, and (subclasses of) exceptions that are
291
+ already defined to be thrown by a class that is subclassed itself. If an
292
+ extension uses external functionality that may throw an exception it MUST wrap
293
+ any exception thrown by that functionality into an appropriate exception of its
294
+ own. It MUST set the ``$previous `` property to the original exception when doing
295
+ so.
296
+
297
+ As an example, an extension that uses the CSPRNG must wrap the
298
+ ``Random\RandomException `` thrown on CSPRNG failure into an appropriate
299
+ extension-specific exception.
300
+
301
+ The ``Error `` hierarchy MUST NOT be used for errors that are expected to be
302
+ thrown (and caught) during normal operation of a PHP program.
303
+
304
+ As an example, a parsing function that is expected to be used with untrusted
305
+ input must not throw an ``Error `` if the input is malformed. Similarly a
306
+ function that interacts with the network must not throw an ``Error `` if the
307
+ network operation fails. Any ``Error `` that is thrown should usually result in a
308
+ reasonably obvious fix in the PHP program.
309
+
310
+ All exceptions MUST have a descriptive exception message intended for human
311
+ consumption. Non-base exceptions MAY define additional properties to provide
312
+ additional metadata about the nature of the error.
313
+
314
+ The exception message MUST NOT be the only means of distinguishing exception
315
+ causes that the user might want to handle differently. Any two exceptions with
316
+ different causes MUST be identifiable either by a unique exception class name, a
317
+ stable ``$code ``, or a class-specific additional property suitable for
318
+ programmatic consumption (e.g. an enum).
319
+
320
+ As an example, in an HTTP client a connection failure due to a timeout is
321
+ considered to be a different cause than a connection failure due to a
322
+ non-existent hostname, as the user might want to schedule a retry when the
323
+ connection times out, but not for unknown hostnames. If using the same
324
+ ``ConnectionFailureException `` class name for both errors, they must provide a
325
+ property suitable for programmatic consumption and may not just differ in their
326
+ exception message.
327
+
232
328
************************
233
329
Implementation Details
234
330
************************
0 commit comments