Improve error handling
This commit is contained in:
parent
87bd780f9f
commit
e6a8150483
7 changed files with 78 additions and 62 deletions
|
|
@ -28,13 +28,14 @@ trait CommandHandler[+Command, +Event, +State]:
|
|||
def commandSchema: Schema[?]
|
||||
|
||||
trait CommandHandlerCreate[Command: Schema, Event] extends CommandHandler[Command, Event, Nothing]:
|
||||
def onCommand(entityId: String, command: Command): Task[Event]
|
||||
def onCommand(entityId: String, command: Command): IO[JsonApiError | Throwable, Event]
|
||||
val isCreate = true
|
||||
val commandSchema = summon[Schema[Command]]
|
||||
|
||||
trait CommandHandlerUpdate[Command: Schema, Event, State]
|
||||
extends CommandHandler[Command, Event, State]:
|
||||
def onCommand(entityId: String, state: State, command: Command): Task[Event]
|
||||
def onCommand(entityId: String, state: State, command: Command)
|
||||
: IO[JsonApiError | Throwable, Event]
|
||||
val isCreate = false
|
||||
val commandSchema = summon[Schema[Command]]
|
||||
|
||||
|
|
@ -45,20 +46,21 @@ class CommandEngine[Command, Event, State](
|
|||
val stateRepo: StateRepository[State]):
|
||||
|
||||
def handleCommand(command: Command, name: String, entityId: String)
|
||||
: Task[(lu.foyer.Event[Event], lu.foyer.Entity[State])] =
|
||||
: IO[JsonApiError | Throwable, (lu.foyer.Event[Event], lu.foyer.Entity[State])] =
|
||||
for
|
||||
handler <- ZIO
|
||||
.succeed(handlers.find(_.name == name))
|
||||
.someOrFail(new IllegalArgumentException(s"No handler found for command $name"))
|
||||
entityOption <- stateRepo.fetchOne(entityId)
|
||||
(event, newStateOption) <- transition(command, name, entityId, entityOption, handler)
|
||||
newState <-
|
||||
newState <-
|
||||
ZIO
|
||||
.succeed(newStateOption)
|
||||
.someOrFail(new IllegalArgumentException("Reducer cannot resolve state transition"))
|
||||
newEntity = Entity(entityId, newState, entityOption.map(_.version).getOrElse(1))
|
||||
_ <- if entityOption.isEmpty then stateRepo.insert(newEntity.entityId, newEntity)
|
||||
else stateRepo.update(newEntity.entityId, newEntity)
|
||||
_ <-
|
||||
if entityOption.isEmpty then stateRepo.insert(newEntity.entityId, newEntity)
|
||||
else stateRepo.update(newEntity.entityId, newEntity)
|
||||
eventEntity <- Random.nextUUID.map(id => Event(newEntity.entityId, event, id.toString))
|
||||
_ <- eventRepo.insert(eventEntity.eventId, eventEntity)
|
||||
yield (eventEntity, newEntity)
|
||||
|
|
@ -69,7 +71,7 @@ class CommandEngine[Command, Event, State](
|
|||
entityId: String,
|
||||
entityOption: Option[Entity[State]],
|
||||
handler: CommandHandler[Command, Event, State]
|
||||
): Task[(Event, Option[State])] = (entityOption, handler) match
|
||||
): IO[JsonApiError | Throwable, (Event, Option[State])] = (entityOption, handler) match
|
||||
case (None, h) if !h.isUpdate =>
|
||||
h.asInstanceOf[CommandHandlerCreate[Command, Event]]
|
||||
.onCommand(entityId, command)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue