Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як повідомити про помилку, не перериваючи запит: хелпери report() і rescue()?

Не кожна помилка має зупиняти запит. Якщо не вдалося оновити рекомендації чи відправити аналітику, користувач усе одно має отримати сторінку - але розробник має про це дізнатися.

report() - передати виняток обробнику для звітування (лог, Sentry) і продовжити виконання:

public function isValid(string $value): bool
{
    try {
        // перевірка, що може кинути виняток
    } catch (Throwable $e) {
        report($e);

        return false;
    }
}

Без report() виняток у catch просто зникає - це «проковтування» помилки, яке роками ховає баги.

rescue() - виконати замикання, а при винятку звітувати й повернути значення за замовчуванням:

$recommendations = rescue(
    fn () => $this->recommender->for($user),
    [],                 // значення при помилці
);

// без звітування - третій аргумент
$preview = rescue(fn () => $this->renderPreview($post), null, report: false);

Значенням за замовчуванням може бути й замикання - воно виконається лише при помилці.

report_if() / report_unless():

report_if($response->failed(), new PaymentGatewayException($response->body()));

Дублікати: якщо той самий виняток передали в report() кілька разів (у сервісі й ще раз у контролері), у лозі з'являться дублікати. $exceptions->dontReportDuplicates() у bootstrap/app.php звітує кожен екземпляр лише раз.

Коли rescue - погана ідея:

  • помилки, від яких залежить коректність: оплата, збереження замовлення, перевірка прав. Тиха заміна на значення за замовчуванням тут перетворює помилку на неправильні дані;
  • широкий блок коду: rescue() навколо половини методу ховає і очікувані, і зовсім несподівані збої. Загортайте лише конкретну необов'язкову операцію;
  • без звітування (report: false) - лише коли помилка справді очікувана і не цікава.

Правило: якщо помилку ловите, то або обробляєте осмислено, або звітуєте. Порожній catch - майже завжди баг.

Докладніше в документації: Помилки: хелпер report

Схожі питання