I am trying to apply a rejection to the aggregate which threw it:
public class WalletAggregate extends Aggregate<WalletId, Wallet, Wallet.Builder> {
@Assign MoneyCharged handle(ChargeMoney cmd) throws InsuffisientFunds {
...
}
@Apply void on(MoneyCharged event) {
...
}
@Apply void on(InsuffisientFunds event) {
...
}
}
I can clearly see the MoneyChanged
event applied. But when InsuffisientFunds
is thrown, it is not applied. Am I missing something? How can I apply a thrown rejection to an aggregate?
Rejections don't work that way. A Rejection is more then just negative-case Event. It is emitted when an illegal operation is attempted and the handler (in your case, the Aggregate) refuses (rejects) to execute the Command, and thus does not change its state.
In practice, you might want to consider creating a separate entity that would process Rejections.
If you want to store the failed actions of a user, a Projection
would probably work best:
public class ChargeAttemptsProjection extends Projection<...> {
@Subscribe
void on(InsuffisientFunds rejection) {
// Update the state of the Projection.
}
}
If there is a flow for recovering from the faulty situation, a ProcessManager
sounds more fit.
public class FailedTransactionRecovery extends ProcessManager<...> {
@React
YourOtherEvent on(InsuffisientFunds rejection) {
// Start the recovery process.
}
}
Last but not least, there's always the possibility to subscribe to the Rejection on the client to handle it gracefully on the UI. See the JS reference documentation for more on client-side subscriptions.