Zwracanie błędów z serwera w redux-form
Kiedy dodajecie formularz w aplikacji webowej pierwsze co robicie to dodajecie do niego takie walidacje jak sprawdzanie czy pole nie jest puste albo czy podana wartość jest faktycznie adresem email. To wszystko dzieje się po stronie frontendu, a jeśli dane będą na tym etapie poprawne to całość leci do serwera. I właśnie pisząc aplikację na konkurs „Daj się poznać” doszedłem do etapu gdzie muszę jakoś obsłużyć zwracanie błędów z tego serwera.
Jakiś czas temu wspominałem, że w projekcie korzystam z biblioteki redux-form. Obsługuje mi ona formularze. Być może niektórzy pamiętają ile się namęczyłem z walidowaniem pól po stronie widoku ;) Tym razem miałem mały problem z obsługą błędów z serwera.
Przykłady, a rzeczywistość
W przykładzie na stronie biblioteki redux-form jest pokazane jak obsłużyć błędy dla poszczególnych pól po submicie. Rzucamy określony wyjątek, do którego przekazujemy obiekt z polem o nazwie takiej samej jak nazwa inputa i zawierającym treść błędu. Proste i działa.
Ale co kiedy chcemy zwrócić bardziej ogólny błąd? Np. co w przypadku jak coś pójdzie nie tak przy pobieraniu danych z bazy i chcemy o tym poinformować? Przecież nie jest to związane z żadnym konkretnym polem na formularzu. Takiego przykładu na stronie redux-form nie znalazłem. Próba wpisania dowolnego pola w przekazywanym obiekcie błędu powoduje błąd informujący o nieznalezieniu inputa o podanej nazwie.
Wyjście z sytuacji
Rozwiązanie znalazłem niejako przy okazji. Przeglądając kod innego projektu natrafiłem na obsługę błędów. Tam zauważyłem tajemnicze pole _error . Przetestowałem fragment kodu i stało się to o co mi chodziło – wyświetliła się treść błędu w miejscu, w którym się jej spodziewałem.
Obsługa błędu z serwera w metodzie wywoływanej po submicie formularza wygląda u mnie tak:
if(result.payload && result.payload.status !== 200) { dispatch(userActions.signInUserFailure(result.payload.data)) dispatch(commonActions.unblockUi()) throw new SubmissionError({ _error: result.payload.data.message }) }
W przypadku zwrócenia status innego niż 200 (powodzenie zapytania) wykonuję akcję dodającą błąd w store i rzucam wyjątek biblioteki redux-form.
I teraz najdziwniejsze. W komponencie „nasłuchuję” wartości dodawanej przez pierwszą akcję:
const mapStateToProps = function (store) { return { isError: store.userState.error != null, error: store.userState.error != null ? store.userState.error.message : null } }
Ale dopóki nie rzucę wyjątku to nie jest ona brana pod uwagę. Co więcej przekazując w wyjątku np. pusty obiekt również nie wyświetla mi się błąd. Pole error jest w store za każdym razem uzupełnione.
Mam wrażenie, które muszę jakoś potwierdzić z dokumentacją, że w tym fragmencie dzieje się magia:
export default connect(mapStateToProps)(reduxForm({ form: 'login-form', validate: Validate })(Login))
W każdym razie kod działa i wyświetla to co ma wyświetlać w przypadku zwrócenia przez serwer błędu.
Leave a Comment