Bir Laravel uygulaması geliştirirken, bir şeyler yanlış gittiğinde abort() fonksiyonuna başvurmak cazip gelebilir, örneğin bir uçuş rezervasyon uygulamasında bir kullanıcıyı uçuşa check-in yapmaya çalışırken:
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="nf">abort</span><span class="p">(</span><span class="mi">422</span><span class="p">,</span> <span class="s1">'Yolcu zaten check-in yaptı.'</span><span class="p">);</span>abort(403, ‘Bu uçuş için boarding durdu.’);
abort(404, ‘Rezervasyon bulunamadı.’);
<p>Kısa bir kontrolcü metodu için bu uygun gibi görünüyor. Ancak uygulamanız büyüdükçe — hizmetler, işlemler, görevler ve konsol komutları aynı iş mantığını paylaştığında — bu <code>abort()</code> çağrıları sorun oluşturmaya başlar.</p>
<h2>
<a name="the-problem-with-raw-abort-endraw-everywhere" href="#the-problem-with-raw-abort-endraw-everywhere">
</a>
<code>abort()</code>'un Her Yerde Olmasının Problemi
</h2>
<p><code>abort()</code> yardımcı fonksiyonu, bir <code>HttpException</code> atarak çalışır ve HTTP bağlamları için tasarlanmıştır. İş mantığınız bir kontrolcünün dışındayken — bir eylem sınıfında, bir hizmette, bir sıraya alınmış işte veya bir CLI komutunda — <code>abort()</code> tamamen yanlış bir araç olur.</p>
<p>Örneğin, bir <code>CheckInAction</code> sınıfı aşağıdakilerden biri tarafından çağrılabilir:</p>
<ul>
<li>Bir web veya API isteğini yöneten bir kontrolcü</li>
<li>Havaalanı personeli için bir Filament eylem butonu</li>
<li><em>(Tamam, British Airways muhtemelen Filament kullanmıyordur, ama sizin uygulamanızın kullanma ihtimali çok daha yüksek!)</em></li>
<li>Otomatik check-in işlemesini gerçekleştiren bir sıraya alınmış iş</li>
</ul>
<p>Eğer bu eylem <code>abort(422, 'Koltuk artık mevcut değil')</code> çağrısını gerçekleştirirse, kontrolcüden çağrıldığında çalışır ama bir iş veya komut için anlamsal olarak yanlıştır — ve eğer bunun için bir birim testi yazarsanız, gerçek domaininizi tanımlayan bir şey yerine <code>HttpException</code> ile test yapıyor olacaksınız.</p>
<p>Daha iyi bir yolu var.</p>
<hr/>
<h2>
<a name="custom-exceptions-as-domain-signals" href="#custom-exceptions-as-domain-signals">
</a>
Domain Sinyalleri Olarak Özel İstisnalar
</h2>
<p>Bu desenin üç parçası var:</p>
<ol>
<li>Her bir domain kavramı için bir <strong>taban istisna</strong> sınıfı, bir <code>getKey()</code> metodu ile başarısızlıkları bir form alanına eşleyen</li>
<li><strong>Somut istisna sınıfları</strong> bunun üzerinde, her bir başarısız senaryo için bir tane</li>
<li>Herhangi bir domain başarısızlığını <code>ValidationException</code>'a dönüştüren bir <strong>kontrolcü yakalayıcı</strong> — frontend’e anlaşılır, tutarlı bir hata yapısı sunma</li>
</ol>
<p>Bu, HTTP ile ilgili endişeleri iş mantığınızdan tamamen dışarıda tutar, aynı zamanda kontrolcünün kullanıcıların anlayacağı bir şekilde hataları yüzeye çıkarmasını sağlar.</p>
<p>Uçuş check-in sistemi için böyle görünür:</p>
<h3>
<a name="step-1-define-a-base-exception" href="#step-1-define-a-base-exception">
</a>
Adım 1: Bir Taban İstisna Tanımlayın
</h3>
<p>Tüm check-in başarısızlıkları ortak bir temel sınıftan türetilir. Buradaki temel tasarım kararı <code>getKey()</code>: her istisna hangi form alanına ait olduğunu bilir, böylece hata, bir doğrulama mesajı olarak yüzeye çıktığında doğru alana hedef alabilir.</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="c1">// app/Exceptions/CheckInException.php</span>namespace App\Exceptions;
use RuntimeException;
abstract class CheckInException extends RuntimeException
{
abstract public function getKey(): string;
}


