<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="https://sandfox.me/assets/xml/atom.xsl" type="text/xsl media="all"?>
<feed xml:lang="en" xmlns="http://www.w3.org/2005/Atom">
  <title>Sand Fox (Posts about good practices)</title>
  <id>https://sandfox.me/tags/good-practices.xml</id>
  <updated>2026-01-05T10:06:10Z</updated>
  <author>
    <name>Anton Smirnov</name>
  </author>
  <link rel="self" type="application/atom+xml" href="https://sandfox.me/tags/good-practices.xml"/>
  <link rel="alternate" type="text/html" href="https://sandfox.me/tags/good-practices.html"/>
  <generator uri="https://getnikola.com/">Nikola</generator>
  <entry>
    <title>Do Not Use Exception Class Directly</title>
    <id>https://sandfox.me/php/do-not-use-exception.html</id>
    <updated>2025-10-09T20:57:00+03:00</updated>
    <published>2024-11-18T23:08:00+02:00</published>
    <author>
      <name>Anton Smirnov</name>
    </author>
    <link rel="alternate" type="text/html" href="https://sandfox.me/php/do-not-use-exception.html"/>
    <summary type="html">&lt;aside class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This post is slightly outdated and needs to be revised to align with PHP's internal policies.
&lt;a class="reference external" href="https://github.com/php/policies/blob/main/coding-standards-and-naming.rst#throwables"&gt;https://github.com/php/policies/blob/main/coding-standards-and-naming.rst#throwables&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While they are aimed at extensions, userspace libraries should benefit from them too.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;It is a bad practice to use the &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; class directly in PHP.
That means 2 points:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Do not throw &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; directly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do not catch &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; directly&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Subclassing &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; is not a direct use in this context.&lt;/p&gt;
&lt;section id="do-not-throw-exception"&gt;
&lt;h2&gt;Do not throw &lt;code class="docutils literal"&gt;Exception&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;There are a lot of specific &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; descendants in PHP.
&lt;a class="reference external" href="https://www.php.net/manual/en/spl.exceptions.php"&gt;See documentation for the full list.&lt;/a&gt;
It's not necessary to use and remember all of them, many have unclear use cases,
but at very least you should separate your exceptions into &lt;code class="docutils literal"&gt;RuntimeException&lt;/code&gt; and &lt;code class="docutils literal"&gt;LogicException&lt;/code&gt;.
As the doc says, &lt;code class="docutils literal"&gt;LogicException&lt;/code&gt; means code misuse.
Throw &lt;code class="docutils literal"&gt;LogicException&lt;/code&gt; in cases when the upstream must be fixed because it uses your code incorrectly.
Throw &lt;code class="docutils literal"&gt;RuntimeException&lt;/code&gt; in cases that are not predictable by the upstream,
like service failures or invalid user input.&lt;/p&gt;
&lt;p&gt;In case you use exceptions for flow control, you need your own custom exceptions anyway.
In this case you can extend the base &lt;code class="docutils literal"&gt;Exception&lt;/code&gt;, extending &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; directly is not a sin,
especially if your exceptions are not error conditions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="do-not-catch-exception"&gt;
&lt;h2&gt;Do not catch &lt;code class="docutils literal"&gt;Exception&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Assuming you follow the previous point, there is no need to catch &lt;code class="docutils literal"&gt;Exception&lt;/code&gt;'s.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;If you don't guard against a specific situation, catch all &lt;code class="docutils literal"&gt;RuntimeException&lt;/code&gt;'s.
&lt;code class="docutils literal"&gt;LogicException&lt;/code&gt;'s should go to your logger.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In a global error handler that writes your logs, you need to catch Errors too,
so you need to go even further and catch &lt;code class="docutils literal"&gt;Throwable&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you use exceptions for flow control (please don't haha) you already catching your own exceptions,
and if you follow the previous point,
they are already separated from actual error conditions and won't be caught mistakenly by a wrong level.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notable exceptions to the rule:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;You use PHP below 7.0 and don't have &lt;code class="docutils literal"&gt;Throwable&lt;/code&gt;.
Well, it's 2024 already so this is another call for you to upgrade.
Otherwise assume point 2 allows you to catch a base &lt;code class="docutils literal"&gt;Exception&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You use a library that throws plain &lt;code class="docutils literal"&gt;Exception&lt;/code&gt; instances.
Well, bad for you, but maybe it's a good idea to report this thing as a problem.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;</summary>
    <category term="good-practices" label="good practices"/>
    <category term="opinion" label="opinion"/>
  </entry>
</feed>
