2010-06-18 3 views
8

Я немного потрудился, но код статуса HTTP не отображается, когда запрос выполняется успешно, но после «точки без возврата» есть ошибка.Код статуса HTTP для «успеха с ошибками»?

Например, скажем, вы обрабатываете запрос, привязанный к базе данных, но при возврате результата вы запускаете память или сталкиваетесь с NPE или тем, что у вас есть. Это : были ответом 200, но теперь внутренне вы не можете вернуть правильный, хорошо сформированный отклик.

202 Accepted не подходит, поскольку мы уже обработали запрос.

Какой код состояния означает «Успех, но ошибки»? Существует ли вообще?

+0

В этом случае вы должны быть уверены, что еще не отправили некоторые данные клиенту, потому что тогда вы уже передали точку без возврата: до первых байтов данных заголовки (включая код состояния) отправлено в браузер. –

+0

Хех - предоставлено :). Наверное, я говорю о том, что-то-нет-возврат перед этой точкой-без-возвращения. Однако большую часть времени серверный код создает полный ответ в памяти перед его отправкой, так как обычно он достаточно мал, чтобы сделать это. –

ответ

3

Если сервер знает, что он столкнулся с проблемой, он должен нормально возвращать ошибку 5xx. Наиболее общим из них является 500 Server Error, которую RFC 2616 определяет следующим образом:

500 Internal Server Error

Сервер столкнулся с непредвиденным условием, которое не позволяет ему выполнить запрос.

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

+1

Я не очень доволен этим ответом. Что именно означает «выполнить»? Мы изменили ресурс любым способом, который запросил клиент. Если они перезагружают страницу, они будут видеть изменения. Что касается пользователя, это было успешным. Для меня это похоже на то, что мы выполнили _request_, но не выполнили _response_. –

+0

@ Рихард: Я всегда понимал «выполнить», чтобы включить ответ (но я мог ошибаться в этом). Тем не менее этот код состояния очень общий, и его следует использовать всякий раз, когда сервер сталкивается с проблемой, которая не может быть описана другой более конкретной ошибкой 5xx. Я думаю, [@Jim] (http://stackoverflow.com/users/45935/jim-ferrans) описал, что я хотел сказать лучше, [в другом ответе] (http://stackoverflow.com/questions/3066972/ HTTP-статус-код-для-успеха-с-ошибок/3067090 # 3067090). –

1

Я согласен с @Daniel, что правильный ответ HTTP 500 (ошибка сервера). Веб-приложение должно быть написано, чтобы отменить транзакцию, когда есть ошибка, а не оставить вещи полузавершенными.

Одна вещь, которую вы можете использовать в своем веб-приложении, - «idempotency». Это свойство функции (или операции), которую вы можете повторять столько раз, сколько хотите, с тем же результатом. Например, если сбой чтения, клиент может просто повторить попытку до тех пор, пока это не удастся. Если удаление удалось, клиент может снова выполнить повторную попытку, и сервер будет обрабатывать запрос как действительный, будет ли удаляемый ресурс уже удален. И если обновление, похоже, терпит неудачу, клиент может повторить попытку, пока он не получит успешный возврат с сервера. Подход REST к архитектуре веб-сервисов сильно использует идемпотентность, чтобы сделать операции надежными перед лицом ошибки.

+0

Чтобы уточнить, транзакция уже совершена (например, рассмотрите случай, когда OutOfMemoryError возникает во время кодирования ответа). Чтобы реализовать idempotency, вам нужно будет реализовать контроль версий, нет? Если сервер отслеживает представленные изменения, а клиенты поставляют и меняют идентификатор. Также существует случай обработки не временных ошибок (скажем, есть ошибка, приводящая к появлению NPE вместо ошибки с памятью) - клиент может повторить все, что захочет, но это никогда не удастся (несмотря на то, что он преуспел в первый раз, а последующие времена являются избыточными). –

+0

@ Рихард: «Все зависит». Если это приложение для управления контентом, и вы не возражаете, если из-за строгого порядка иногда появляются два «одновременных» обновления, вам не нужно выполнять управление версиями. Но проверка версий или timestamping может быть уместна, если у вас есть более жесткие ограничения. Другой подход заключается в том, чтобы сформировать как можно больший объем ваших ответов в рамках транзакции, так что OOME приведет к прекращению транзакции. И, возможно, постоянные очереди сообщений, содержащие запросы и результаты транзакций, могут быть тем, что вы хотите (проверьте ActiveMQ от Apache). +1 для зондирующих вопросов! –

4

HTTP-код не имеет такого кода состояния, но существует наилучшая практика, позволяющая обрабатывать такие ситуации - перенаправить пользователя после операции POST.

Вот ломаются -

  1. Запрос POST пытается изменить данные на сервере
  2. Если сервер выходит из строя, он посылает ошибку 500, чтобы указать отказ
  3. Если сервер успешно, он посылает ответ переадресации 302
  4. браузер посылает запрос на свежий GET на сервер
  5. Если это не удается, вы получаете ошибку 500, в противном случае вы получите 200

Итак, ваш вариант использования «Сохраненные данные, но не может его немедленно восстановить» переводит на перенаправление 302 для начального POST, а затем 500 для последующего GET.

Этот подход имеет другие преимущества - вы избавляетесь от раздражающего «Вы уверены, что хотите повторно отправить данные?» сообщение. Также позволяет использовать кнопки back/forward/refresh.

Смежные вопросы