Как обработать возникшую ошибку в PHP скрипте загрузки страницы?

Весь PHP код пишется в следующем блоке:

try{
   ...
}catch (Exception $e){
   http_response_code(500);
}

При вылете исключения, я устанавливаю код ответа сервера 500. Так робот индексирующий страницу поймёт, что в работе сайта произошла ошибка. Но этого не поймёт пользователь, т.к. страница просто будет пустой. Как при вылете исключения сделать редирект на страницу ошибки 500?

В .htaccess прописано следующее:
ErrorDocument 500 /pages/error_500.php
Но редирект всё равно не происходит.
  • Вопрос задан
  • 669 просмотров
Решения вопроса 2
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Это очень хороший вопрос, по многим причинам.

Во-первых, очень хорошо что он сам по себе поставлен. Обычно пользователи РНР не задумываются о таких "мелочах". Но на самом деле об этом должен думать каждый программист, делающий сайты
Во-вторых, здесь мы можем видеть довольно характерный баг Апача, который действительно, почему-то не выполняет директиву ErrorDocument для 500 ошибок, полученных от РНР. Ну и вообще, завязываться на Апач во времена доминирования Нжинкса как-то не очень дальновидно.
В-третьих, как правильно заметил Stalker_RED, сделать редирект при 500 статусе (или 500 статус при редиректе) невозможно - статус может быть только один. Да это и нет смысла делать - проще сразу на месте нужную страницу и прочитать.
В-четвертых, текущий подход, прямо скажем, не очень оптимальный:
- о роботах мы позаботились, о пользователе позаботились, но надо ещё не забыть и программиста. Которому как раз сообщение об ошибке-то нужно видеть во всех подробностях!
- просто отдать нужный НТТР код недостаточно - надо бы ещё и завершить работу скрипта.
- ловить все ошибки вручную через try-catch так себе удовольствие. И код раздувает,и поведение потом быстро не поменяешь. А если в какой-то момент захочется для отладки прикрутить whoops - это придётся по всем блокам бегать?

Чтобы решить все эти проблемы разом, надо сделать единый обработчик ошибок. Который и подробности для программиста залогирует, и нужный заголовок отправит, и красивый хтмл юзеру покажет.

В самом простом варианте это будет что-то вроде такого:

set_exception_handler(function ($e)
{
    error_log($e);
    http_response_code(500);
    if (ini_get('display_errors')) {
        echo $e;
    } else {
        include 'pages/error_500.php';
    }
});

В теории, конечно, можно заменить error handler на глобальный try-catch который оборачивает точку входа, но это менее удобно. Тем более, что для обработки фатальных ошибок нужен свой отдельный обработчик, и в итоге код обработки ошибок начинает занимать довольно значительный объем и лучше конечно его инициализацию вынести отдельно.
Ответ написан
Комментировать
Stalker_RED
@Stalker_RED
Редирект это 3xx, а ошибка это 5xx.
Вы не можете отдать два статуса одновременно.

Но вы можете отдав 500 отдать и содержимое страницы.
header('HTTP/1.1 500 Internal Server Error', true, 500);
readfile("my500page.html");
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы