Hibakezelés
A projekten fontos szempont, hogy általánosan kezeljük a hibákat. A projekten ezt úgy valósítjuk meg, hogy a kliensek irányába típusában általános hibaüzeneteket küld a szerveroldal amit egy központi hibakezelő logika állít elő.
1. Általános hibaüzenet
A szerveroldali alkalmazás az összes szerveroldali hibaüzenetet egy központi hibakezelő logikával általános típusú hibaüzenetre.
Az általános hibaüzenet egy tetszőleges számú SystemMessage-et tartalmazó SystemMessageResponse típusú objektum.
A SystemMessage az alábbi mezőket tartalmazza:
level: Azaz, hogy milyen szintű üzenetről van szó, Pl.: Hiba (ERROR), Figyelmeztés (WARNING) stb.code: Egy azonosító kód, ami minden üzenetet egyedileg azonosít.params: Az üzenet opcionális paramétereinek listája. Pl.: Fix hosszúságú mező esetén a karakterek maximális száma stb.message: Maga a szerver által lefordított hibaüzenet.fieldName: Amennyiben az üzenet valamilyen mezőre vonatkozik itt található az érintett mező neve.type: Az üzenet típusa. Arra vonatkozik, hogy a hibaüzenet a klienstől érkező kérésre (REQUEST) vagy csak egy bizonyos mezőre (FIELD) vonatkozik.exceptionTraceId: Hibaazonosító, amely egyedien azonosítja az összetartozó, kliensnek leküldött és backend logba mentett hibaüzeneteket.
Hol definiáljuk a SystemMessageResponse-t?
A SystemMessageResponse típus a kontrakt része ezért az OpenAPI definíciós fájlunk tartalmazza.
Az OpenAPI definicíós fájlról részletesebben itt olvashatsz.
2. Szerveroldali hibakezelés
2.1 A BaseExceptionHandler szerepe
Az általános hibaüzeneteket a szerveroldal állítja elő.
A szerveren keletkező összes kivételt (Exception) a BaseExceptionHandler osztály kezeli és alakítja át a SystemMessageResponse típusra.
A BaseExceptionHandler egy úgynevezett RestControllerAdvice típusú @Bean. Segítségével az összes Controller osztályra
érvényes globális hibakezelő logikát implementálhatunk benne.
Ebből következően a BaseExceptionHandler metódusai állítják elő az általános hibaüzenetet a szerveroldali Exception-ök alapján.
Az hogy melyik metódus, mely Exception-ért felel az @ExceptionHandler annotációval konfigurálható.
2.2 A SystemMessage létrehozása és használata
A SystemMessage szerveroldalon példányosítható objektum.
Ha a szerveroldalon valamilyen hibát szükséges dobni, akkor ehhez RuntimeException-ből származó SystemRuntimeErrorException-t használjuk.
A SystemRuntimeErrorException számos konstruktora lévén lehetőséget biztosít, hogy tetszőleges számú SystemMessage objektumot átadva példányosítsuk.
Az így átadott SystemMessage-eket majd az előző pontban taglalt BaseExceptionHandler fogja felhasználni.
A SystemMessage létrehozásakor a fejlesztő felelőssége azt megfelelően paraméterezni az Általános Hibaüzenet bekezdésben kifejtett mezők kitöltésével.
Fontos
A SystemMessage objektum fieldName mezőjének kitöltésekor vegyük figyelembe, hogy a kliens alkalmazások ezen érték alapján jelenítenek meg hibaüzeneteket.
Pl.: Ha nem a formátumoknak megfelelő email címet írtuk be a regisztrációs formon, akkor az email input mező alatt jelenik meg a hibaüzenet.
Ahhoz azonban, hogy ez minden esetben működjön, a fieldName mezőbe a request DTO szerinti hierarchiát tükrözően kell megadni a mező nevét.
A fenti példából kiindulva ha a request az alábbi módon néz ki:
fieldName-nek az alábbi értéket kell tartalmaznia: personalInfo.email.
3. Kliensoldali hibakezelés
Amikor a kliens feliratkozik egy API hívásra, akkor egy observable objektumon keresztül át kell adni a sikeres vagy sikertelen válasz esetén végrehajtandó kódot.
A kliensoldali fejlesztéseknél sikertelen válasz, azaz hiba esetén a FormErrorHandler -> next metódusának kell átadni az error objektumot.
A FormErrorHandler működése
A FormErrorHandler első lépésben eltávolítja a formról a korábbi hibaüzeneteket.
(Pl.: Ha egy korábbi API hívás miatt már vannak hibaüzenetek a formon. Ilyenkor annak érdekében hogy csak az új hibaüzenetek jelenjenek meg a korábbi hibaüzeneteket el kell távolítania.)
Ezt követően a HTTP válaszból kiveszi a SystemMessage-eket, végigiterál rajtuk, és amennyiban a SystemMessage type
mező értéke FIELD, úgy a fieldName mező alapján a form megfelelő fieldjeihez hozzárendeli a message mezőben küldött hibaüzenetet.