Comments (5)
Using domain events to model failures is how you'd solve the problem currently.
Instead of your aggregate returning an {:error, :no_available_seats}
error, it should raise a domain event such as FlightReservationFailed
and could provide the failure as a field (e.g. reason: :no_seats_available
). Your travel process manager can then subscribe to both success and failure events and handle each appropriately. It would dispatch cancellation commands in the case of any step failure.
A benefit to using domain events for errors is they provide useful auditing and analytics. The business might find it convenient to report on these events in the future to answer pertinent questions (e.g. "how often do we fail to reserve seats on flights for airline X?").
There's a pending issue to add a retry/error handling mechanism to event handlers and process managers (#20). This feature would allow your aggregate to return error tuples, or raise an exception, and provide an extension point in your process manager to handle errors on a case-by-case basis. But it needs to be implemented.
Does that answer your question?
from commanded.
Yes, that seems a good idea. So the point is to return these events, but in the cases where this is a CreateX command it should not create a valid aggregate, right? By returning an event, we assume it worked and that we can fold over the events to get the state of the aggregate, which actually shouldn't exist. How would you work in that situation?
Just allowing the aggregate to "exist" but actually in an "invalid" state?
Also, if domain errors are just events, how can I know that a command worked after dispatching it? Also, what is the point to returning {:error, reason}
? Which kind of errors you think I should return in the tuple and witch you think I should return in events?
from commanded.
It's ok to have an aggregate in such a state, think of it as an unfulfilled reservation request rather than an "error state". You can use Commanded's Aggregate lifespan feature to shutdown these aggregates after an error event if you are concerned with them running indefinitely.
how can I know that a command worked after dispatching it?
You receive an :ok
response from a successful command dispatch, or an {:error, reason}
when it fails. However, by using failure domain events the command will successfully dispatch (returning :ok
). You will need an event handler to handle these events and notify the end user as appropriate (alert email, in-app notification, use Phoenix channels to push the failure to the user's browser).
The general pattern with long running processes, such as your reservation, is to notify the user that their request was accepted, start processing the request in the background, and inform the user that they will be notified upon success/failure. One approach is to have a read model projection for the reservation that is updated from the domain events. As an example if you're building a web app, after successful submission you redirect the user to a page that polls/subscribes the user to updates of their reservation status.
what is the point to returning {:error, reason}? Which kind of errors you think I should return in the tuple and witch you think I should return in events?
As a rule of thumb, use domain events for failures of commands dispatched by a process manager. You can use {:error, reason}
tuples elsewhere and to guard against bugs (e.g. attempting to reserve a flight for a date in the past).
from commanded.
@bamorim You can now handle errors in your process managers using the new feature described in #93.
Here's your example travel process manager responding to seat failure by cancelling the hotel and car reservations:
defmodule TravelProcessManager do
use Commanded.ProcessManagers.ProcessManager,
name: "TravelProcessManager",
router: TravelRouter
def error({:error, :no_available_seats}, _failed_command, _pending_commands, context) do
{:continue, [%CancelHotel{...}, %CancelCar{...}], context}
end
end
Now you can choose to model failures as errors (e.g. {:error, :no_available_seats}
) or domain events (e.g. FlightReservationFailed
).
from commanded.
from commanded.
Related Issues (20)
- warning: redefining module Commanded.Serialization.JsonDecoder.Any HOT 2
- Event number gaplessness required?
- Commanded.aggregate_state does not work when aggregate identity has a prefix HOT 10
- Process manager router option not working
- Lessons learned from performance optimization - an unlikely culprit HOT 3
- no function clause matching in Commanded.Commands.Dispatcher.telemetry_stop/3 HOT 1
- Docs questions
- Stacktrace in event handler error? HOT 2
- Paralelization Strategies in EventHandlers
- Should Commanded.Event.Handler support messages from swarm? HOT 2
- Event retention policies?
- please support multiple commanded application with one eventstore HOT 6
- Process Manager state serialization breaks when using a custom TypeProvider with the JsonSerializer
- `Commanded.ProcessManagers.ProcessManager.identity/0` function returns `nil` in unit tests
- no function clause matching in Commanded.Event.Handler.partition_event/4 HOT 1
- EventstoreDB is sunsetting the TCP protocol HOT 1
- Is it a bad practice for an event handler to depend on a projector completion? HOT 2
- Snapshotting 2 Aggregates having same identity
- Is it possible to log contents of InMemoryEventStore on failed test?
- Ecto Sandbox, Projections and In Memory adapter HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from commanded.