Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean architecture : where should I put my exceptions?

First off, I present you the context. I am writing an api in C# and ASP.NET Core and I am trying to follow the clean architecture.

In summary : I don't know where to put my exceptions. I have written a little scenario where I explain my logic.

  1. Suppose that I throw a DuplicatePersonException in a concrete gateway.
  2. This exception will be caught by my use case (interactor) as a simple exception. I don't think that the use case has to know the real exception.
  3. When I catch the error, I will call a method in my OutputBoundary (presenter).
  4. In the end, this presenter will format the answer and prepare an adequate ActionResult based on DuplicatePersonException.

If I respect the « inward dependency », I have to put my DuplicatePersonException in my use case layer. Why not in the domain layer ? Because it does not have to know this kind of exception. What's more, I don't know if I have to create an abstract custom exception and extends it both in the gateway layer and in the presenter layer : it makes me a little bit confused.

In fine, this solution doesn’t sound good to me but I am not able to explain why. It does not feel right to put my exceptions in this layer.

In conclusion, if you have any advice or solution, I will accept them with great pleasure !

Thank you very much for trying to help me !

like image 259
P. Orlando Avatar asked May 05 '20 08:05

P. Orlando


People also ask

Which layer should handle exceptions?

The Controller layer is where the Domain Exceptions will be treated. Take into account that in this case, the unexpected exceptions are caught by the layer that throws her and also by the rest of the upper layers.

How do you use exceptions correctly?

The method to choose depends on how often you expect the event to occur. Use exception handling if the event doesn't occur very often, that is, if the event is truly exceptional and indicates an error (such as an unexpected end-of-file). When you use exception handling, less code is executed in normal conditions.

Should a library throw an exception?

If the error is something that cannot be recovered from, there is no need for you to throw an error (in JS). Your library should be able to fallback gracefully to alternatives but if it cannot do that for a certain function, it should return undefined.

What is clean architecture?

With Clean Architecture, the Domain and Application layers are at the centre of the design. This is known as the Core of the system. The Domain layer contains enterprise logic and types and the Application layer contains business logic and types.

How to handle exceptions in a project?

It is pretty easy and straightforward to setup centralized exception handling and logging. This is probably best done at the beginning of a project so that all peer developers follow the same approach. Any newly defined exceptions can be added and handled in a consistent manner.

How to create a clean architecture solution using the parent folder?

The template "Clean Architecture Solution" was created successfully. This command will create a new solution, automatically namespaced using the name of the parent folder. For example, if the parent folder is named Northwind, then the solution will be named Northwind.sln, and the default namespace will be Northwind.

Is there a clean architecture for DTO?

It's not "clean architecture" but "vertical slice architecture" but that shouldn't matter. Put the classes close to where they're actually used. Show activity on this post. In your case,the DTO is accessed by both Presentation & Domain. so better to have it Infrastructure and refer it from there. Thanks for contributing an answer to Stack Overflow!


1 Answers

(I think the image in this classic article illustrates the layers in the question, if "entities" and "domain" is the same thing: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)

First, there is no point in throwing exceptions that the calling code cannot catch. Then you might as well throw Exception instead.

This is the same idea as returning entities. If your entities were defined in your gateway, your use case wouldn't be able to receive them.

Say your gateway fetches a PersonEntity from the database or an external API. In clean architecture, PersonEntity should be defined in your gateway, and mapped to another PersonEntity in the domain, and then mapped to another PersonDto in the presentation.

These entities are completely separate; none of them extend the other. That would defeat the purpose, I think.


Here's my suggestion:

Define and catch DuplicatePersonException in your use case layer.

Define another, more general exception in your domain layer (maybe InvalidDataException), and throw this from your use case (or forward in a method call).

like image 77
Christian Davén Avatar answered Oct 23 '22 23:10

Christian Davén