Как сказать обработчику ошибок, что нужен джейсон а не хтмл?

Фанат

oncle terrible
Команда форума
Ну вот собственно моя прелессть, базовый обработчик ошибок. Он меня всем устраивает, даже тем что плюет на собак.
Но одна вещь сидит занозой.

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

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

Предупреждение - речь о настоящих ошибках, то есть тех, что случаются непредвиденно, сами по себе. Те, которые мы сами ловим или генерим - понятное дело, можем сами и отправить. Вопрос именно в последнем рубеже, который хендлит неотловленные ошибки. И выдаёт не сообщение об конкретной ошибке, а стандартные извинения.

или не париться, и оставить всё как есть, а ЖС обязать проверять код ответа?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Эта тема достойна доклада на мастерклассе или статьи.
  1. есть ошибки конвертируемые (e.g. type errors), отлавливаемые, неотлавливаемые (compile-time fatal) и совсем неотлавливаемые(segfault, timeout)
  2. в разных версиях обработка немного разная
  3. если обработчики повесить в preload - обработать можно даже фатал в бутстрапе, но не не только лишь все могут прелоад
  4. любую проблему php можно отловить на уровне Nginx, по 502 или timeout отпроксировать на другой upstream, и оттуда отдать json
Так что, начнем разговор.
Какой рубеж для тебя последний?
 

fixxxer

К.О.
Партнер клуба
Проверять заголовок Accept, например.

Но совсем "последний рубеж", конечно, в продакшене в любом случае надо обрабатывать на уровне веб-сервера (fatal error, php-fpm упал и т.д.). Если уж так хочется джаваскрипту сунуть json в 500-м ответе (хотя не очень понимаю, зачем, статуса достаточно), это и nginx-ом можно разрулить через map на http_accept.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
да, в общем случае задача решается на уровне кластера (в терминах кубернетиса) или стека (в docker swarm),
ну или что там у вас по высокоуровневой архитектуре
просто вопрос ошибок php по своей сути уровнем выше, чем php-приложение, а частный случай надо уточнить - какие именно ошибки, как надо обработать
 

Фанат

oncle terrible
Команда форума
Какой рубеж для тебя последний?
Все ошибки РНР, которые в теории можно поймать РНР скриптом, но по которым никакого отдельного сценария не предусмотрено - то есть из всего интерактива с клиентом по ним тупо отдаётся 500. Ну и страничка с извинениями если это запрос из браузера.
 

Фанат

oncle terrible
Команда форума
хотя не очень понимаю, зачем, статуса достаточно
ну вот пожалуй именно это твопрос меня и беспокоит в первую оченедь, как я сейчас понял.
Насколько стандартно для жс библиотек отслеживать статус и говорить что-то осмысленное пользователю в этом случае? или всё ручками?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а что, в библиотеках JS есть станадарты? ))))
в этом же прикол - когда в PHP начали наводить порядок, народ стал переходить в более хаотичный JS
 

fixxxer

К.О.
Партнер клуба
Насколько стандартно для жс библиотек отслеживать статус и говорить что-то осмысленное пользователю в этом случае? или всё ручками?
Ну ты сам понимаешь, что http-клиент не должен ничего говорить. :) Инфраструктура отдельно, UI отдельно.
Любой современный http-клиент возвращает Promise (или Observable), и по умолчанию для "ошибочных" статусов (40х, 50х) делает reject.
А дальше уж зависит от архитектуры приложения, что там в catch написать. У меня, например, есть централизованный обработчик, который кидает событие, по которому показывается ошибка (при этом я, конечно, различаю 40x и 50x, для 40x часто требуется особая обработка в контексте конкретного запроса). В чем тут отличие между обработкой статуса и обработкой тела ответа, мне решительно непонятно (с телом писанины даже больше, делать дополнительную middleware, которая сделает reject, увидев в ответе error).
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
обработка на клиенте - вопрос из другой области, просто в middleware нам хочется обеспечить консистентный внешний API, чтобы считать себя красавцами, а других - говношлепами

например, можно обосновать это тем, что JSON-ответ можно задокументировать в swagger, чем облегчить жизнь другим разработчикам и тестировщикам, но на выживаемость проекта при падении ВВП на 40% это не влияет вообще совсем нисколько
 

fixxxer

К.О.
Партнер клуба
когда в PHP начали наводить порядок, народ стал переходить в более хаотичный JS
Вот поэтому я и предпочитаю Angular - там порядок и typescript. Но, конечно, подход с хаосом вокруг реакта намного более распространен =)
 

Фанат

oncle terrible
Команда форума
Ну короче я понял - не париться, статуса достаточно :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
не ну, ты ж понимаешь, если это enterpriZe - потрать пол-года и соблюди стандарт, сможешь выступить на конфе, и рассказать какие вы молодцы много денег компания смогла потратить не на фичи
 

Фанат

oncle terrible
Команда форума
Кстати
Проверять заголовок Accept, например.
а как проверять?
У меня как-то не очень вяжется проверка НТТР заголовка в обработчике ошибок.
Вот изначально и было вопрос, как это всё связать.

Ну то есть да, это самый тупой в смысле деревянный вариант. Но как-то у меня от него чешется.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
не, это реально плохой костыль, заголовка Accept запросто может и не быть - ну, вот у меня недавно был десктопный клиент на QT, например, а у разработчика началась истерика, и уволился,
или клиента вообще нет - job в kubernetes, или просто cli в контейнере, а ошибки надо вывести в stderr, там их поймают
 

fixxxer

К.О.
Партнер клуба
У меня как-то не очень вяжется проверка НТТР заголовка в обработчике ошибок.
У тебя там уже есть отправка 500-го статуса, соответственно, это HTTP-шный обработчик ошибок. Он вполне может быть классом с HttpRequest и HttpResponseFactory в конструкторе. Если что-то в Accept от нас ожидают, значит, и надо ответить с таким Content-Type (при условии, что тело вообще не нулевой длины, если только статус, это, конечно, не важно). А если заголовка нет, ну, выводим что-то по умолчанию, может, вообще plain text.

Конечно, этот класс может наследоваться от абстрактного обработчика, и у него могут быть другие реализации - Cli-шный, который выводит в stderr, "для демонов", который шлет в сислог, и т.д.
 
Последнее редактирование:

флоппик

promotor fidei
Команда форума
Партнер клуба
Немножко анрилейтед, но летсенкрипт пр ошибках отвечает с контент тайпом application/problem+json - мне эта идея нравится
 

fixxxer

К.О.
Партнер клуба
Немножко анрилейтед, но летсенкрипт пр ошибках отвечает с контент тайпом application/problem+json - мне эта идея нравится
Да, идея таким образом уточнять не вложенный формат (типа xhtml+xml), а конкретную схему, хорошая, отлично ложится на идеи полноценного restful.
 
Сверху