2010-06-18 17 views
8

Poświęciłem trochę, ale nie widzę kodu statusu HTTP, gdy żądanie się powiedzie, ale po "punkcie bez powrotu" jest błąd.Kod stanu HTTP dla "sukcesu z błędami"?

np. Powiedz, że przetwarzasz żądanie, jego zatwierdzenie do bazy danych, ale zwracając wynik, uruchamiasz pamięć lub napotykasz NPE lub co masz. To byłoby odpowiedzią, ale teraz, wewnętrznie, nie jesteś w stanie zwrócić właściwej, dobrze sformułowanej odpowiedzi.

202 Accepted wydaje się nie pasować, ponieważ już przetworzyliśmy wniosek.

Jaki kod statusu oznacza "Sukces, ale błędy"? Czy ktoś istnieje?

+0

W takim przypadku musisz mieć pewność, że nie wysłałeś jeszcze niektórych danych do klienta, ponieważ wtedy przeszedłeś już punkt bez powrotu: przed pierwszymi bajtami danych nagłówki (w tym kod statusu) są wysłane do przeglądarki. –

+0

Heh - przyznane :). Chyba mówię o punkcie bez powrotu przed tym punktem bez powrotu. W większości przypadków kod po stronie serwera buduje pełną odpowiedź w pamięci przed wysłaniem, ponieważ zwykle jest na tyle mały, aby to zrobić. –

Odpowiedz

3

Jeśli serwer ma świadomość, że napotkał problem, powinien zwykle zwrócić błąd 5xx. Najbardziej generic jeden jest 500 Server Error, których RFC 2616 definiuje się następująco:

500 serwera Wewnętrzny błąd

Serwer napotkał nieoczekiwany warunek, który uniemożliwił mu od spełnienia żądania.

Następnie klient jest odpowiedzialny za ponowne podjęcie próby. Jeśli poprzedni wniosek został częściowo zatwierdzony, odpowiedzialność za jego odtworzenie ponosi użytkownik serwera (lub bazy danych) lub odpowiednie przetwarzanie zduplikowanej transakcji.

+1

Nie jestem usatysfakcjonowany tą odpowiedzią. Co dokładnie oznacza "spełnienie"? Zmodyfikowaliśmy zasób w dowolny sposób, o jaki poprosił klient. Jeśli przeładują stronę, zobaczą zmiany. Jeśli chodzi o użytkownika, to się udało. Dla mnie brzmi to tak, jakbyśmy spełnili prośbę, ale nie spełniliśmy odpowiedzi. –

+0

@Richard: Zawsze rozumiałem "spełnij", aby uwzględnić również odpowiedź (ale mogę się mylić). Niemniej jednak ten kod statusu jest bardzo ogólny i powinien być używany zawsze, gdy serwer napotka problem, którego nie można opisać innym, bardziej specyficznym błędem 5xx. Myślę, że [@Jim] (http://stackoverflow.com/users/45935/jim-ferrans) opisał, co zamierzałem powiedzieć lepiej, [w drugiej odpowiedzi] (http://stackoverflow.com/questions/3066972/ http-status-kod-for-success-with-errors/3067090 # 3067090). –

1

Zgadzam się z @Daniel, że właściwą odpowiedzią jest HTTP 500 (błąd serwera). Aplikacja internetowa musi zostać napisana, aby wycofać transakcję, gdy wystąpi błąd, nie zostawiając rzeczy na wpół ukończonych.

Jedną z rzeczy, którą możesz wykorzystać w swojej aplikacji internetowej, jest "idempotencja". Jest to właściwość funkcji (lub operacji), którą możesz powtarzać tyle razy, ile chcesz, z tym samym wynikiem. Na przykład, jeśli odczyt się nie powiedzie, klient może po prostu go powtórzyć, dopóki nie uda się. Jeśli usunięcie nie powiedzie się, klient może ponownie spróbować, a serwer potraktuje żądanie jako prawidłowe, niezależnie od tego, czy usunięty zasób już zniknął. A jeśli aktualizacja się nie powiedzie, klient może spróbować ponownie, dopóki nie uda się uzyskać prawidłowego zwrotu z serwera. Podejście REST do projektowania usług sieciowych w dużym stopniu wykorzystuje idempotencję, aby operacje były niezawodne w obliczu błędów.

+0

Aby wyjaśnić, transakcja jest już zatwierdzona (np. Należy rozważyć przypadek, gdy wystąpi OutOfMemoryError podczas kodowania odpowiedzi). Aby wdrożyć idempotency, musisz wdrożyć kontrolę wersji, nie? Mając serwer śledzić przesłane zmiany i podać i zmienić identyfikator klienta. Jest również przypadek obsługi błędów nie-tymczasowych (np. Błąd powodujący błąd NPE zamiast błędu braku pamięci) - klient może ponowić próbę, ale nigdy nie odniesie sukcesu (mimo że odniósł sukces za pierwszym razem, a kolejne są zbędne). –

+0

@Richard: To "wszystko zależy". Jeśli jest to aplikacja do zarządzania treścią i nie przeszkadza Ci, że czasami wydaje się, że dwie "symultaniczne" aktualizacje odbywają się w ściśle określonej kolejności, nie musisz wykonywać wersji. Ale wersja lub znacznik czasu mogą być odpowiednie, jeśli masz bardziej rygorystyczne ograniczenia. Innym podejściem jest sformułowanie tak dużej części odpowiedzi w ramach transakcji, jak to możliwe, więc KILKA spowodowałoby przerwanie transakcji. A może trwałe kolejki komunikatów przechowujące żądania transakcji i wyniki mogą być tym, czego potrzebujesz (sprawdź ActiveMQ firmy Apache). +1 za pytania do sondowania! –

4

HTTP nie ma takiego kodu statusu, ale istnieje najlepsza praktyka, która pozwala na obsługę takich sytuacji - przekierowanie użytkownika po operacji POST.

Oto rozbicie -

  1. żądanie POST próbuje modyfikować dane na serwerze
  2. Jeśli serwer nie wysyła błąd 500 do zasygnalizuje awarię
  3. Jeśli serwer się powiedzie, to wysyła odpowiedź 302 przekierować
  4. przeglądarka wysyła świeżego GET żądanie do serwera
  5. Jeśli to się nie powiedzie, pojawi się błąd 500, inaczej dostaniesz 200

Tak więc, Twój przypadek użycia "Zapisanych danych, ale nie może go natychmiast odzyskać", przekłada się na przekierowanie 302 dla początkowego testu POST, a następnie 500 dla następnego GET.

Takie podejście ma inne zalety - pozbędziesz się irytujących "Czy na pewno chcesz ponownie przesłać dane?" wiadomość. Utrzymuje również przyciski wstecz/przewijania/odświeżania.

Powiązane problemy