Aktywne Wpisy
FoczanPingwianu +614
Pijcie ze mną kompot. W piątek zakończyłem roczny maraton w IT. Postanowiłem sobie rok temu, że poświęcę prawie cały swój czas na pracę - w najgorętszych okresach nawet 18h 6 dni w tygodniu. Przerwa na spanie, jakieś jedzenie i trochę zabawy z dziećmi. Brałem wszystkie zlecenia jak leci. Teraz miesiąc albo dwa urlopu i wracam do normalnego życia. Udało mi się zrobić na czysto 1.6mln zł, co jest dla mnie potężną dawką

Salido +268
Minął 23. (z 66) dzień wakacji.
W ciągu ostatniej doby miało miejsce 7 wypadków śmiertelnych w których zginęło 7 osób.
103 wypadki drogowe ze skutkiem śmiertelnym od początku wakacji.
106 ofiar śmiertelnych w wypadkach drogowych od początku wakacji.
W ciągu ostatniej doby miało miejsce 7 wypadków śmiertelnych w których zginęło 7 osób.
103 wypadki drogowe ze skutkiem śmiertelnym od początku wakacji.
106 ofiar śmiertelnych w wypadkach drogowych od początku wakacji.
źródło: 1-453841-8
Pobierz




Mam jeden interface na wszystkie błędy:
public interface ResponseError {String getMessage();
int getHttpCode();
}
Przykładowe enum:
public enum UserError implements ResponseError {
//normalnie jest ich oczywiście więcej
EMPTY_USERNAME_OR_PASSWORD("Empty username or password", 400),
DUPLICATED_USERNAME("Duplicated username", 400);
private int httpCode;
private String message;
UserError(String message, int httpCode) {
this.httpCode = httpCode;
this.message = message;
}
@Override
public String getMessage() {
return message;
}
@Override
public int getHttpCode() {
return httpCode;
}
}
Narzuciłem sobie, aby wszystkie fasady zwracały:
Either extends ResponseError, ?Dzięki temu mam jeden generyczny mapper:
public final class ResponseResolver {
private ResponseResolver() {}
static ResponseEntity resolve(Either extends ResponseError, ? input) {
return input
.map(ResponseEntity::ok)
.getOrElseGet(ResponseResolver::createErrorResponse);
}
private static ResponseEntity createErrorResponse(ResponseError error) {
ErrorResponse response = new ErrorResponse(error.getMessage());
int httpCode = error.getHttpCode();
return new ResponseEntity<>(response, HttpStatus.valueOf(httpCode));
}
//Bonusowo na tej samej zasadzie działa z Option (Optionalem)
public static ResponseEntity resolve(Option input) {
return input
.map(x -> new ResponseEntity<>(x, HttpStatus.OK))
.getOrElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
(Gdzie klasa ErrorResponse jest zwykłym DTO z jednym polem, żeby wynik był jsonem)
No i teraz w kontrolerze (na przykładzie springa):
@PostMapping("login")public ResponseEntity generateToken(@RequestBody LoginUserInfo loginUserInfo) {
Either userDetails = userFacade.login(loginUserInfo);
return ResponseResolver.resolve(userDetails);
}
No i właściwie to tyle ;)
Powyższe rozwiązanie ma właściwie pewną wadę: miesza warstwy. Czy jest to problem? Zazwyczaj nie, bo i tak pisze się soft dedykowany pod pracę na serwerach i nikt go w inny sposób nie odpala. Dodatkowo ta nadmiarowa informacja w postaci kodu http i wiadomości nie przeszkadza w żaden sposób w odpaleniu kodu np. z konsoli. Rozwiązaniem tego mógłby być osobny mapper w warstwie http, ale to już wchodzi trochę w sztukę dla sztuki, więc wydaje mi się, że taki kompromis pomiędzy pragmatycznością, a łamaniem abstrakcji między warstwami jest jeszcze akceptowalny.
#java #webdev #programowanie
co jest w tym złego?
To mam jeszcze inne pytanie, jak obsługujesz wyjątki które nie lecą w twoim kodzie tylko w jakieś klasie z liba? robisz try { } catch { } przy każdym wywołaniu zewnętrznej klasy która może rzucić wyjątek?
Imho takie coś jest dużo bardziej czytelne:
@