From aa929f6b2615ea66dc96b3daf8c505fa3c2d7388 Mon Sep 17 00:00:00 2001 From: jbion Date: Mon, 19 Dec 2016 02:35:57 +0100 Subject: Improve error output --- .../sevenwonders/controllers/LobbyController.java | 12 +++-- .../controllers/UniqueIdAlreadyUsedException.java | 15 ------- .../luxons/sevenwonders/errors/ErrorFactory.java | 52 ++++++++++++++++++++++ .../org/luxons/sevenwonders/errors/ErrorType.java | 7 +++ .../org/luxons/sevenwonders/errors/UIError.java | 42 +++++++++++++++++ .../errors/UniqueIdAlreadyUsedException.java | 15 +++++++ .../sevenwonders/errors/UserInputException.java | 14 ++++++ .../java/org/luxons/sevenwonders/game/Lobby.java | 2 +- src/main/resources/static/app.js | 3 +- 9 files changed, 142 insertions(+), 20 deletions(-) delete mode 100644 src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java create mode 100644 src/main/java/org/luxons/sevenwonders/errors/ErrorFactory.java create mode 100644 src/main/java/org/luxons/sevenwonders/errors/ErrorType.java create mode 100644 src/main/java/org/luxons/sevenwonders/errors/UIError.java create mode 100644 src/main/java/org/luxons/sevenwonders/errors/UniqueIdAlreadyUsedException.java create mode 100644 src/main/java/org/luxons/sevenwonders/errors/UserInputException.java diff --git a/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java index 7567c330..e15935d6 100644 --- a/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java +++ b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java @@ -7,6 +7,8 @@ import java.util.Map; import org.luxons.sevenwonders.actions.JoinOrCreateGameAction; import org.luxons.sevenwonders.actions.StartGameAction; +import org.luxons.sevenwonders.errors.ErrorFactory; +import org.luxons.sevenwonders.errors.UIError; import org.luxons.sevenwonders.errors.UniqueIdAlreadyUsedException; import org.luxons.sevenwonders.game.Game; import org.luxons.sevenwonders.game.Lobby; @@ -36,6 +38,8 @@ public class LobbyController { private final SimpMessagingTemplate template; + private final ErrorFactory errorFactory; + private long lastGameId = 0; private Map lobbies = new HashMap<>(); @@ -43,16 +47,18 @@ public class LobbyController { private Map games = new HashMap<>(); @Autowired - public LobbyController(GameDefinitionLoader gameDefinitionLoader, SimpMessagingTemplate template) { + public LobbyController(GameDefinitionLoader gameDefinitionLoader, SimpMessagingTemplate template, + ErrorFactory errorFactory) { this.gameDefinitionLoader = gameDefinitionLoader; this.template = template; + this.errorFactory = errorFactory; } @MessageExceptionHandler @SendToUser("/queue/errors") - public String handleException(Throwable exception) { + public UIError handleException(Throwable exception) { logger.error("An error occured during message handling", exception); - return exception.getClass().getSimpleName() + ": " + exception.getMessage(); + return errorFactory.createError(exception); } @MessageMapping("/create-game") diff --git a/src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java b/src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java deleted file mode 100644 index 56c22655..00000000 --- a/src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.luxons.sevenwonders.controllers; - -public class UniqueIdAlreadyUsedException extends RuntimeException { - - private String id; - - public UniqueIdAlreadyUsedException(String id) { - super("'" + id + "'"); - this.id = id; - } - - public String getUsedId() { - return id; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/ErrorFactory.java b/src/main/java/org/luxons/sevenwonders/errors/ErrorFactory.java new file mode 100644 index 00000000..2d3dcd0b --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/errors/ErrorFactory.java @@ -0,0 +1,52 @@ +package org.luxons.sevenwonders.errors; + +import java.util.List; +import java.util.Locale; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException; +import org.springframework.stereotype.Component; +import org.springframework.validation.ObjectError; + +@Component +public class ErrorFactory { + + private static final String ERROR_CODE_VALIDATION = "VALIDATION_ERROR"; + + private static final String ERROR_MSG_VALIDATION = "Input invalid"; + + private final MessageSource messageSource; + + @Autowired + public ErrorFactory(MessageSource messageSource) { + this.messageSource = messageSource; + } + + public UIError createError(Throwable exception) { + if (exception instanceof UserInputException) { + return createUserError((UserInputException)exception); + } else if (exception instanceof MethodArgumentNotValidException) { + return createValidationError((MethodArgumentNotValidException)exception); + } else { + return createInternalError(exception); + } + } + + private UIError createUserError(UserInputException exception) { + String messageKey = exception.getMessageResourceKey(); + String message = messageSource.getMessage(messageKey, null, messageKey, Locale.US); + return new UIError(messageKey, message, ErrorType.USER); + } + + private UIError createInternalError(Throwable exception) { + return new UIError(exception.getClass().getSimpleName(), exception.getMessage(), ErrorType.INTERNAL); + } + + private UIError createValidationError(MethodArgumentNotValidException exception) { + List errors = exception.getBindingResult().getAllErrors(); + UIError uiError = new UIError(ERROR_CODE_VALIDATION, ERROR_MSG_VALIDATION, ErrorType.VALIDATION); + uiError.setValidationErrors(errors); + return uiError; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/errors/ErrorType.java b/src/main/java/org/luxons/sevenwonders/errors/ErrorType.java new file mode 100644 index 00000000..71df185f --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/errors/ErrorType.java @@ -0,0 +1,7 @@ +package org.luxons.sevenwonders.errors; + +public enum ErrorType { + USER, + VALIDATION, + INTERNAL +} diff --git a/src/main/java/org/luxons/sevenwonders/errors/UIError.java b/src/main/java/org/luxons/sevenwonders/errors/UIError.java new file mode 100644 index 00000000..67802f22 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/errors/UIError.java @@ -0,0 +1,42 @@ +package org.luxons.sevenwonders.errors; + +import java.util.List; + +import org.springframework.validation.ObjectError; + +public class UIError { + + private final String code; + + private final String message; + + private final ErrorType type; + + private List validationErrors; + + public UIError(String code, String message, ErrorType type) { + this.code = code; + this.message = message; + this.type = type; + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public ErrorType getType() { + return type; + } + + public List getValidationErrors() { + return validationErrors; + } + + public void setValidationErrors(List validationErrors) { + this.validationErrors = validationErrors; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/errors/UniqueIdAlreadyUsedException.java b/src/main/java/org/luxons/sevenwonders/errors/UniqueIdAlreadyUsedException.java new file mode 100644 index 00000000..b1b00453 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/errors/UniqueIdAlreadyUsedException.java @@ -0,0 +1,15 @@ +package org.luxons.sevenwonders.errors; + +public class UniqueIdAlreadyUsedException extends RuntimeException { + + private String id; + + public UniqueIdAlreadyUsedException(String id) { + super("'" + id + "'"); + this.id = id; + } + + public String getUsedId() { + return id; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/errors/UserInputException.java b/src/main/java/org/luxons/sevenwonders/errors/UserInputException.java new file mode 100644 index 00000000..11f7f8f2 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/errors/UserInputException.java @@ -0,0 +1,14 @@ +package org.luxons.sevenwonders.errors; + +public class UserInputException extends RuntimeException { + + private final String messageResourceKey; + + public UserInputException(String messageResourceKey) { + this.messageResourceKey = messageResourceKey; + } + + public String getMessageResourceKey() { + return messageResourceKey; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/Lobby.java b/src/main/java/org/luxons/sevenwonders/game/Lobby.java index 7fdffef5..16d4e8a3 100644 --- a/src/main/java/org/luxons/sevenwonders/game/Lobby.java +++ b/src/main/java/org/luxons/sevenwonders/game/Lobby.java @@ -3,7 +3,7 @@ package org.luxons.sevenwonders.game; import java.util.ArrayList; import java.util.List; -import org.luxons.sevenwonders.controllers.UniqueIdAlreadyUsedException; +import org.luxons.sevenwonders.errors.UniqueIdAlreadyUsedException; import org.luxons.sevenwonders.game.data.GameDefinition; public class Lobby { diff --git a/src/main/resources/static/app.js b/src/main/resources/static/app.js index b1881357..ace23fdb 100644 --- a/src/main/resources/static/app.js +++ b/src/main/resources/static/app.js @@ -19,7 +19,8 @@ function connect() { console.log('Connected: ' + frame); stompClient.subscribe('/user/queue/errors', function (msg) { - console.error(msg.body); + var error = JSON.parse(msg.body); + console.error(error); }); stompClient.subscribe('/topic/games', function (msg) { -- cgit