Une exception on the command.run to notify the player instead on direct send

This commit is contained in:
2025-03-14 21:02:37 +01:00
parent 5a5e7ab7cf
commit 7d06babdeb
8 changed files with 35 additions and 28 deletions

View File

@@ -0,0 +1,5 @@
package eventDemo.app.command
class CommandException(
override val message: String,
) : Exception(message)

View File

@@ -14,7 +14,7 @@ fun errorNotifier(
): ErrorNotifier = ): ErrorNotifier =
{ {
val logger = KotlinLogging.logger { } val logger = KotlinLogging.logger { }
ErrorNotification(message = it) ErrorNotification(message = it, command = command)
.let { notification -> .let { notification ->
logger.atWarn { logger.atWarn {
message = "Notification ERROR sent: ${notification.message}" message = "Notification ERROR sent: ${notification.message}"

View File

@@ -19,13 +19,16 @@ class GameCommandRunner(
outgoingErrorChannelNotification: SendChannel<Notification>, outgoingErrorChannelNotification: SendChannel<Notification>,
) { ) {
val gameState = gameStateRepository.getLast(command.payload.aggregateId) val gameState = gameStateRepository.getLast(command.payload.aggregateId)
val errorNotifier = errorNotifier(command, outgoingErrorChannelNotification)
try {
when (command) { when (command) {
is IWantToPlayCardCommand -> command.run(gameState, errorNotifier, this.eventHandler) is IWantToPlayCardCommand -> command.run(gameState, this.eventHandler)
is IamReadyToPlayCommand -> command.run(gameState, errorNotifier, this.eventHandler) is IamReadyToPlayCommand -> command.run(gameState, this.eventHandler)
is IWantToJoinTheGameCommand -> command.run(gameState, errorNotifier, this.eventHandler) is IWantToJoinTheGameCommand -> command.run(gameState, this.eventHandler)
is ICantPlayCommand -> command.run(gameState, errorNotifier, this.eventHandler) is ICantPlayCommand -> command.run(gameState, this.eventHandler)
}
} catch (e: CommandException) {
errorNotifier(command, outgoingErrorChannelNotification)(e.message)
} }
} }
} }

View File

@@ -1,6 +1,6 @@
package eventDemo.app.command.command package eventDemo.app.command.command
import eventDemo.app.command.ErrorNotifier import eventDemo.app.command.CommandException
import eventDemo.app.entity.GameId import eventDemo.app.entity.GameId
import eventDemo.app.entity.Player import eventDemo.app.entity.Player
import eventDemo.app.event.GameEventHandler import eventDemo.app.event.GameEventHandler
@@ -26,12 +26,10 @@ data class ICantPlayCommand(
suspend fun run( suspend fun run(
state: GameState, state: GameState,
playerErrorNotifier: ErrorNotifier,
eventHandler: GameEventHandler, eventHandler: GameEventHandler,
) { ) {
if (state.currentPlayerTurn != payload.player) { if (state.currentPlayerTurn != payload.player) {
playerErrorNotifier("Its not your turn!") throw CommandException("Its not your turn!")
return
} }
val playableCards = state.playableCards(payload.player) val playableCards = state.playableCards(payload.player)
if (playableCards.isEmpty()) { if (playableCards.isEmpty()) {
@@ -46,7 +44,7 @@ data class ICantPlayCommand(
) )
} }
} else { } else {
playerErrorNotifier("You can and must play one card, like ${playableCards.first()::class.simpleName}") throw CommandException("You can and must play one card, like ${playableCards.first()::class.simpleName}")
} }
} }
} }

View File

@@ -1,6 +1,6 @@
package eventDemo.app.command.command package eventDemo.app.command.command
import eventDemo.app.command.ErrorNotifier import eventDemo.app.command.CommandException
import eventDemo.app.entity.GameId import eventDemo.app.entity.GameId
import eventDemo.app.entity.Player import eventDemo.app.entity.Player
import eventDemo.app.event.GameEventHandler import eventDemo.app.event.GameEventHandler
@@ -26,7 +26,6 @@ data class IWantToJoinTheGameCommand(
suspend fun run( suspend fun run(
state: GameState, state: GameState,
playerErrorNotifier: ErrorNotifier,
eventHandler: GameEventHandler, eventHandler: GameEventHandler,
) { ) {
if (!state.isStarted) { if (!state.isStarted) {
@@ -38,7 +37,7 @@ data class IWantToJoinTheGameCommand(
) )
} }
} else { } else {
playerErrorNotifier("The game is already started") throw CommandException("The game is already started")
} }
} }
} }

View File

@@ -1,6 +1,6 @@
package eventDemo.app.command.command package eventDemo.app.command.command
import eventDemo.app.command.ErrorNotifier import eventDemo.app.command.CommandException
import eventDemo.app.entity.Card import eventDemo.app.entity.Card
import eventDemo.app.entity.GameId import eventDemo.app.entity.GameId
import eventDemo.app.entity.Player import eventDemo.app.entity.Player
@@ -28,16 +28,13 @@ data class IWantToPlayCardCommand(
suspend fun run( suspend fun run(
state: GameState, state: GameState,
playerErrorNotifier: ErrorNotifier,
eventHandler: GameEventHandler, eventHandler: GameEventHandler,
) { ) {
if (!state.isStarted) { if (!state.isStarted) {
playerErrorNotifier("The game is Not started") throw CommandException("The game is Not started")
return
} }
if (state.currentPlayerTurn != payload.player) { if (state.currentPlayerTurn != payload.player) {
playerErrorNotifier("Its not your turn!") throw CommandException("Its not your turn!")
return
} }
if (state.canBePlayThisCard(payload.player, payload.card)) { if (state.canBePlayThisCard(payload.player, payload.card)) {
@@ -50,7 +47,7 @@ data class IWantToPlayCardCommand(
) )
} }
} else { } else {
playerErrorNotifier("You cannot play this card") throw CommandException("You cannot play this card")
} }
} }
} }

View File

@@ -1,6 +1,6 @@
package eventDemo.app.command.command package eventDemo.app.command.command
import eventDemo.app.command.ErrorNotifier import eventDemo.app.command.CommandException
import eventDemo.app.entity.GameId import eventDemo.app.entity.GameId
import eventDemo.app.entity.Player import eventDemo.app.entity.Player
import eventDemo.app.event.GameEventHandler import eventDemo.app.event.GameEventHandler
@@ -24,20 +24,20 @@ data class IamReadyToPlayCommand(
override val player: Player, override val player: Player,
) : GameCommand.Payload ) : GameCommand.Payload
@Throws(CommandException::class)
suspend fun run( suspend fun run(
state: GameState, state: GameState,
playerErrorNotifier: ErrorNotifier,
eventHandler: GameEventHandler, eventHandler: GameEventHandler,
) { ) {
val playerExist: Boolean = state.players.contains(payload.player) val playerExist: Boolean = state.players.contains(payload.player)
val playerIsAlreadyReady: Boolean = state.readyPlayers.contains(payload.player) val playerIsAlreadyReady: Boolean = state.readyPlayers.contains(payload.player)
if (state.isStarted) { if (state.isStarted) {
playerErrorNotifier("The game is already started") throw CommandException("The game is already started")
} else if (!playerExist) { } else if (!playerExist) {
playerErrorNotifier("You are not in the game") throw CommandException("You are not in the game")
} else if (playerIsAlreadyReady) { } else if (playerIsAlreadyReady) {
playerErrorNotifier("You are already ready") throw CommandException("You are already ready")
} else { } else {
eventHandler.handle(payload.aggregateId) { eventHandler.handle(payload.aggregateId) {
PlayerReadyEvent( PlayerReadyEvent(

View File

@@ -1,12 +1,17 @@
package eventDemo.app.notification package eventDemo.app.notification
import eventDemo.configuration.UUIDSerializer import eventDemo.configuration.UUIDSerializer
import eventDemo.libs.command.Command
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import java.util.UUID import java.util.UUID
sealed interface CommandStateNotification : Notification
@Serializable @Serializable
data class ErrorNotification( data class ErrorNotification(
@Serializable(with = UUIDSerializer::class) @Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(), override val id: UUID = UUID.randomUUID(),
val message: String, val message: String,
) : Notification val command: Command,
) : Notification,
CommandStateNotification