Replies: 1 comment 1 reply
-
I see it as coupling only when you catch the errors thrown by an external library. If in the service we were catching domain-driven-hexagon/src/libs/db/sql-repository.base.ts Lines 112 to 118 in ee02993 Our domain is aware that a record may already exist in a database, thus it needs some kind of conflict error. You could return it instead of throwing to make it more explicit and define it in an interface: interface RepositoryPort<Entity> {
insert(entity: Entity): Promise<Result<Entity, ConflictError>>
// ...
} This way domain explicitly knows about the error that it expects. But again, I don't see it as coupling because we explicitly defined this exception and know what to expect, we don't catch |
Beta Was this translation helpful? Give feedback.
-
In your example code, specifically here:
domain-driven-hexagon/src/modules/user/commands/create-user/create-user.service.ts
Line 38 in ee02993
you are converting an Exception throw by the specific Adapter's implementation of your Repository Output Port into an error value, in order to avoid propagating the Exception.
While it is fine to avoid an Exception-driven flow, now your Application Service must have knowledge about the Exceptions that the implementation of one of your Output Ports (in this case a Repository) deals with, therefore coupling your Application Core to the implementation details and ruining the Dependency Inversion principle that you tried to preserve using the Repository interface itself.
What do you think about this? Is this some trade-off that you intentionally agreed somehow?
Looking forward to hearing your feedback!
Beta Was this translation helpful? Give feedback.
All reactions