Can you use try/catch to control logic?
- Can you use try catch to control logic? I've been using it so far, but today I came across a claim that it's not a good practice.
- How resource-intensive are nested try catch blocks? I read that try catch itself is "cheap", but throw requires a lot of resources. Is that true?
1. Can you use try/catch to control logic?
Yes, you can, and it's a perfectly workable approach. The question here isn't "right/wrong", but which philosophy is closer to you and what fits a particular architecture.
In fact, it's a very holy-war topic.
There's a camp that says "exceptions are only for exceptional situations", and there's a camp that calmly uses them as a flow control mechanism. And both approaches get along just fine.
Personally, I think it's a matter of convenience, not an absolute truth. The object-oriented approach is more convenient for me. IMHO, if code reads better, the approach has a right to exist.
An example:
try {
$code = $repo->getByUrl($url);
} catch (NotFoundException) {
$code = $this->generateAndSave($url);
}
In this situation it works naturally and clearly: "not there? create it". There's nothing wrong with catching a specific exception and doing fallback logic.
Problems start only when an exception is used instead of a plain if in the simplest places, or when a repository starts throwing exceptions where returning null is expected. But that's a question of code design.
2. Is throw really expensive?
Yes, that's true.
try/catch by itself costs almost nothing. You can even nest them — the overhead is negligible, but throw is expensive, because PHP generates a backtrace and creates a full-fledged Exception object, which eats CPU.
So:
- If
throwhappens rarely — it's not a problem at all. - If "not found" becomes a normal execution path (often), then it's worth considering whether it's simpler to return null or a Result object — purely from a performance standpoint.
But even here everything depends on the context. If the load is small, the difference doesn't matter at all.
To sum up my position
- You can use try/catch for logic. It's not a bad practice in itself, it's a matter of taste, style and team.
- If code reads better, I'm always for it.
- try/catch is cheap, throw is more expensive, but in real projects it rarely becomes a bottleneck.
If it's convenient for you and fits the architecture, keep using it.
First published in Ukrainian in the Telegram channel “Created to die” on November 14, 2025.