前回の記事で、LogicException(バグ)とRuntimeException(環境エラー)の違いについてお話ししました。
「違いはわかったけど、実際の開発でどう役立つの?」
そう思った方もいるかもしれません。 実は、この使い分けを徹底すると、「運用の楽さ」 が劇的に変わるんです!
今回は実践編として、「例外の種類によって、Slack通知やエラー画面を自動で振り分ける方法」 をご紹介します。
すべてのエラーを通知していませんか?
開発現場でよくあるのが、「エラーが出たら全部Slackに通知!」という運用。 これ、最初はいいんですが、だんだんこうなりませんか?
-
深夜に「DB接続タイムアウト」の通知が来て叩き起こされる(でも数秒後に自然復旧してる)
-
通知が多すぎて、本当に重要なバグ報告を見逃す
-
結果、「通知チャンネル誰も見なくなる」 現象が発生…
これは、「バグ(緊急)」 と 「環境トラブル(要確認)」 を混ぜてしまっているのが原因です。
「型」で振り分ける実装パターン
ここで、前回の知識が活きてきます。 例外ハンドラー(エラーを一元管理するクラス)で、以下のように振り分けてみましょう。
use Psr\Log\LoggerInterface;
class AppExceptionHandler
{
public function __construct(
private LoggerInterface $logger,
private SlackNotifier $slack
) {}
public function handle(\Throwable $e): void
{
// パターン1:LogicException / DomainException
// 意味:「コードがおかしい(バグ)」
if ($e instanceof \LogicException) {
// これは緊急事態!開発者にすぐ知らせる
$this->logger->critical($e->getMessage());
$this->slack->send("🚨 緊急: 実装バグが発生!すぐ直して!: " . $e->getMessage());
// ユーザーには「システムエラー」とだけ表示
$this->renderErrorPage(500);
return;
}
// パターン2:RuntimeException
// 意味:「外部要因で失敗(環境エラー)」
if ($e instanceof \RuntimeException) {
// ログには残すけど、深夜に叩き起こすほどではないかも
$this->logger->error($e->getMessage());
// ユーザーには「現在混み合っています」など、やんわり伝える
$this->renderErrorPage(503);
return;
}
// その他の予期せぬエラー
$this->logger->error('Unknown Error: ' . $e->getMessage());
$this->renderErrorPage(500);
}
}
この設計のメリット
こうすることで、開発チームの動き方が変わります。
-
Slack通知が来たら「即対応」
-
LogicExceptionだけが通知されるので、「通知 = 自分のコードミス」と認識できます。
-
-
ログが綺麗になる
-
一時的な接続エラーなどはログファイルに溜まるだけなので、精神衛生上とても良いです(もちろん定期的なチェックは必要ですよ!)。
-
-
ユーザーへの案内が親切になる
-
バグなら
500、アクセス過多なら503と、状況に合わせたHTTPステータスコードを返せます。
-
例外処理は「未来の自分」へのメッセージ
例外クラスを使い分けることは、単なるルールではありません。
-
LogicException を投げるときは、「これバグだから絶対直してね!」というメッセージ。
-
RuntimeException を投げるときは、「運用でカバーしてね」というメッセージ。
この意図を込めてコードを書けるようになると、一人前のエンジニアへまた一歩近づけます。 「エラーハンドリング」という地味な部分ですが、こここだわるとカッコいいですよ!
ぜひ、自分たちのプロジェクトにも導入できないか検討してみてくださいね。

