LINUX.ORG.RU

Сигнализировать ошибку в процессе передачи ответа

 ,


0

1

Каким образом сервер может вернуть ошибку, если он уже отослал заголовки? Пусть даже без сообщения, просто сам факт, чтобы клиент мог понять, что на сервере что-то не так и не продолжать выполнять нормальную логику. Приходит в голову только «тупо» закрыть соединение в надежде на то, что ответ в виде какого-нибудь JSON-а вернётся невалидным и клиент свалится на парсинге или что длина ответа не совпадёт с Content-Length или ответ будет содержать невалидный чанк, если ответ не содержит длины. А если ответ уже полностью записан? Дописать ещё мусора?

★★★★★

Последнее исправление: Legioner (всего исправлений: 2)

Нужно читать рфц. По поводу закрытия до того как передал весь ответ — скорее всего и в рфц и в реализациях будет вылазить ошибка. Про дописывание мусора не удивлюсь если найдутся клиенты которые плюют на рфц что бы там не было написано по этому поводу.

Возможно хттп не твой выбор. Те же вебсокеты могут подойти лучше

redixin ★★★★
()

ошибку в процессе передачи ответа

если ответ уже полностью записан

А можете в двух словах рассказать как у вас это получается? Ну там пример какой-то или хоть на пальцах?

micronekodesu ★★★
()

Каким образом сервер может вернуть ошибку, если он уже отослал заголовки?

Правильный ответ: не надо ничего отсылать клиенту до того, как вы успешно сформировали нужный ответ. Тогда, если у вас что-то глюканет, вы сможете вернуть нужный HTTP-статус и тело ответа с диагностической инфой. Обычно так делают.

Если же вы жестко поставлены в такую ситуацию, когда серверная среда может начать передачу HTTP-ответа без вашего разрешения, или, к примеру, вы возвращаете какой-то монстровый по размерам ответ, который нужно передавать по мере его формирования (и при этом реально могут возникнуть ошибки), тогда вам нужно предусмотреть наличие в теле HTTP-ответа какого-то флажка, добавляемого в конце - только и всего. Ну и анализировать значение этого флажка на стороне клиента.
Ну и не забывайте, что ошибки бывают не только при формировании ответа, но и при его передаче.

vinvlad ★★
()
Ответ на: комментарий от micronekodesu

А можете в двух словах рассказать как у вас это получается? Ну там пример какой-то или хоть на пальцах?

Как ошибка может возникнуть в середине? Ну самый банальный пример - просят у тебя файл. Ты его открыл и начал передавать, читая с диска и записывая в сокет. В середине тебе операционная система сказала I/O Error. Диск там поломался или NFS-шара отвалилась или ещё что-то.

Как в конце может возникнуть ошибка? Ну тут уже сложней, но всякие ситуации могут быть. Тот же пример с файлом. Ты передал Content-Length равный длине файла из метаданных ФС, прочитал эту длину, а файл не кончился. Значит что-то тут не так. Кто-то его дописывать начал может или ещё что. В любом случае ситуация непонятная и продолжать работу в нормальном режиме нельзя, в том числе клиенту.

Legioner ★★★★★
() автор топика
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от Legioner

Выглядит надуманным. А если в середину файла кто-то запишет что-нибудь? Файл уйдёт битым, и никакой способ ошибку даже не обнаружит.

IMO, если в процессе происходит что-то неожиданное, нет смысла заморачиваться, можно просто соединение сбросить.

i-rinat ★★★★★
()
Ответ на: комментарий от Legioner

(Хоть и было удалено, но это важно.)

Бывают ещё реверс-прокси, или веб-акселераторы. Если ты не контролируешь полностью всю систему, проверь поведение хотя бы в популярных: Nginx, Varnish, Apache Traffic Server, и подобных.

i-rinat ★★★★★
()
Ответ на: комментарий от vinvlad

Правильный ответ:

Правильный ответ был дан выше — chunked + trailer.

redixin ★★★★
()
Ответ на: комментарий от Legioner

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

А вообще, если в файл кто-то пишет, а ты этого не знал, то ты уже screwed, и твои попытки это попытки ловить комаров в лесу. Просто не парься, это код обрабатывающий то, что по главной задумке никогда не произойдет. Что если начало файла поменялось после отправки? Что если файл был удален в процессе выдачи, а ты даешь клиенту уверенность в его существовании? Волей не волей начнешь задумываться, как бы так сделать изоляцию запросов, чтобы один запрос делал типа снапшот файла, а другой менял и это было видно только для следующих. Или если два меняют, то они могли бы блокировать логические области, чтобы не менять связанные части одновременно. Как банковские транзакции. Вот бы была такая софтина, она бы помогла тебе оч сильно.

anonymous
()
Ответ на: комментарий от anonymous

У меня нет никаких протоколов. Я пишу инфраструктурный код. Мне дают хендлер, я его вызываю, он что-то делает, посылает ответ и тд и может свалиться с исключением. Исключение означает, что что-то пошло не так и той стороне надо просигнализировать универсальную ошибку. Я хочу написать универсальную реакцию на это исключение. Если статусный код ещё не отправлен, всё просто - шлём 500, опционально стектрейс исключения шлём, не суть. Вопрос в том, что делать, если этот хендлер, про который я ничего не знаю (могу только отследить, отослал ли он статус и какой тип ответа) уже отослал статус 200, например, и, возможно, начал писать ответ, то ли с Content-Length, то ли чанками.

Legioner ★★★★★
() автор топика
Ответ на: комментарий от Legioner

и, возможно, начал писать ответ,

И тут связь с клиентом пропала...

то ли с Content-Length,

Ну вот и ответ, клиент получивший разрыв соединения то ли по сбросу на сервере, то ли по по пути, то ли по no route to host, то ли по таймауту, обычно понимает, что ему дошло не всё. Это то как раз просто. Обычно сложность в том, как возобновить, если это какая-то динамика по генерации контента.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от Legioner

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

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

vinvlad ★★
()
Ответ на: комментарий от i-rinat

Правда, не факт, что все прокси и акселераторы корректно такое обрабатывают.

И клиенты

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.