Don’t judge just yet and let me fill you in.
When I got promoted to the Head of PHP position, I gained a new perspective and set of responsibilities — quality analysis and broadly understood research.
I quickly noticed that exceptions in PHP lack proper attention.
It’s usually presented as programming construct that you should use, and it’s rarely discussed beyond that.
Shame, because exception design is a very wide topic.
Therefore, I would like to share my discoveries with you — this article will cover why exceptions are usually ignored by PHP developers, when to use them, and how to create them in such a way that they’ll make debugging easier.
Getting started with exception design in PHPMeet Ron — my imaginary friend.
He’s a freelance developer who makes landing sites and portfolios.
All jokes aside, he’ll help us to illustrate some problems here.
So, Ron decided he’s fed up with the accounting and debt collection, so he got a job in an IT company which provides services to various clients.
He got his first task: a general abstraction on the filesystem (he got an ID representing the resource).
He eagerly went to his desk and came up with this:We have the year 2019 and PHP 7, which is why at Code Review one of his colleagues recommended using types and signalling somehow that an error occurred.
Ron reviewed and adjusted his code:Then he heard that it won’t work because PHP errors are converted into exceptions in the project, and he should consider SPLFileInfo in the solution.
Well, he went back to the documentation and created this:I’m not exaggerating here.
You’ve probably seen this type of code in your own experience.
Why PHP developers forget about exception design?Now, why so many developers misuse exceptions or don’t understand them?.From my personal working experience with PHP developers, I can point out three major reasons:For starters, PHP is a very easy language which is awesome.
However, its availability has a drawback.
Having such a mature community, it’s easy for beginners to skip some basics.
You can use one or two frameworks or libraries and you can do pretty advanced stuff without deep knowledge.
In other words, it’s easy to skip exceptions in the learning process.
PHP has historical baggage which misleads and confuses not only beginner programmers.
Just by looking at the documentation you’ll see what I mean.
The language is schizophrenic by having many equivalents both in a procedural and objective style.
Now, as a beginner, what would lure you more?.For many people, procedures seem to be a simpler and more effective choice.
This way, bad habits and primitive driven development is advocated.
Many PHP veterans remember the times when PHP was purely procedural (good ol’ “back in the days”).
You’d be surprised how many of them haven’t really advanced.
They carry outdated knowledge and transfer it while mentoring.
Ok, having that covered, let’s check on Ron.
Are exceptions necessary in every business case?Our developer has learned from very helpful colleagues that exceptions are a nice mechanism that allows you to objectively signal problems in your code.
On his second day at work, Ron was asked to implement a mortgage calculator.
Learning from his new experiences, he created the following code.
Question merges — was it necessary to use an exception here?.Assuming that Ron expects the $loadDeptorRequest object should contain data allowing correct calculation of the loan — that would be totally fine.
However, let’s imagine a business case where you have to check profiles on a mass scale and speed up the process.
You assume that the data doesn’t necessarily have to be complete and when it happens, you return the information.
Since we expect a set of data to be incorrect, is this exception still in place?.In my opinion, no — the situation is no longer special.
You can get rid of it and choose something more accurate, for example, Result Object.
If you don’t know what a Result Object is, I’ll present it at the end of the article.
When should you use exceptions?There are a lot of opinions on where exactly you should use exceptions.
Excluding the official definition, I’ve selected two most distinguished thoughts in the IT community:Exceptions should be used when the situation is exceptional — everywhere where you step out from the happy path.
The exceptions serve primarily to improve readability, so you use them in such a way that the readability of the code increases.
Personally, I am in favour of the second option.
The object-oriented programming was created to make it easier to manage code’s complexity, and to manage it well, it must be readable.
However, it’s no revelation.
That’s why I am talking about the art of exceptions design.
Everyone interprets art in their own way and it’s the same with exceptions.
You need to decide something and stick to it to the very end.
Having this in mind, it may be difficult for us to design an exception somewhere in our code, especially when we start to be aware of exception design.
So how to approach this?.Where to place them?.It’s quite simple but tricky.
Before making a decision, I always look at these two factors: problem’s likelihood and application or business severity.
Seems obvious and probably you already know it but sometimes there are situations where this isn’t so easy.
This is quite simple for probability because the rule is trivial — if something is really likely or often to happen, you probably need something else than an exception (and by that, I don’t mean to fall back to primitives right away).
There’s plenty of other objective ways to handle problematic situations.
For instance, an object repository.
Should it throw an exception on a failing object fetch or maybe just pass back a null or a Null Object?.Well, of course, it depends.
What if this is a domain-specific repository?.Or just an ordinary doctrine repository?.In these situations, you should ask yourself how critical it is in your business context to treat it as something exceptional?If it’s fairly critical, then the answer is simple — use an exception.
Including exceptionsYou know already that the inclusion of exceptions depends on the business context and the problem probability, as we have covered that, but how do you create exceptions so they are useful and readable?.I think everyone will say that there’s nothing hard about designing exceptions — easy-peasy.
Well, let’s see what Ron is up to…He used a very typical exception that I’ve seen a million times before.
At first glance, everything seems fine, but let’s analyse how helpful is it.
We don’t really know the reason why our document couldn’t be signed.
The name of the exception is very generic and doesn’t contribute much to understanding our problem.
We didn’t receive anything that could help us diagnose the problem.
In order to fix it now, we need to work on the first and second point.
It would be nice to know where the problem lies.
In our example, we can obtain this information using the status code.
Let’s name the exception after the problem.
Better, isn’t it?.Now, everybody looking at this will have a better understanding of the problem’s origin.
Next, we need to think about contributing to future maintainers.
Is there a better place where you can find information about the problem than the actual source of the problem?. More details