1

I have a question about the clean architecture I use to write my project, I need to tackle the subject of exceptions. In the project I am using CQRS which is located in the application layer and which orchestrates the whole operation and component connection. In the domain layer, I have domain objects that have some logic, if there is an error this layer throws an exception BusinessRuleValidationException, or NullReferenceException in this layer I only use these 2 exceptions, but now I have an infrastructure layer which, if necessary, also throws exceptions, but there are more of them in this layer and they will probably continue to grow as the application develops.

Now the question is how to solve this problem, which are exceptions that I wouldn't want to keep remembering about handling every single exception inside api using exception middleware. My idea is to leave the exceptions in the domain layer as they are, because there are only 2 and write a decorator to MediatR that will catch exceptions from the domain layer only and make them consistent across the api, i.e. add a unified response so that exceptions are not sent to the user from its internal message, only consistent for everyone, in the form of Result using the Fluent Results bundle. Instead of throwing exceptions in Infrastructure, use a Fluent Results package that will return errors instead of exceptions and eventually return Result from all MediatR Handers. I would not like to use Fluent Result inside the domain layer because it is kind of breaking the rule that the domain layer doesn't have any references to other things.

The next question, if I decide to solve the problem in one way or another, the results of errors from the Infrastructure should immediately contain an error code such as Api should return to the end user, e.g. if occurs an error because it is impossible to connect to the database, the infrastructure should return, the message (Result) under the title "Could not connect to the database" with the code "500", or rather this error code should be returned from the api itself, ie the controller gets an error (Result) and it decides what code to give to this error.

Thanks for help :)

1 Answers1

1

Exceptions aren't a problem that you need to solve. Exceptions are there to say something unexpected has happened, and there are many many things that can go wrong: incorrect input, timeouts, not authorised, not authenticated, missing data, etc, etc.

You can structure your code, where it reuses .net exceptions as much as possible, and if you have to add something that is unique to your business domain, you put that in the layer that throws those exceptions. If this happens at the networking level, you put exceptions there. If this is domain logic validation - you can keep it in the domain core.

Consuming code may or may not catch the exception. If it catches the exception, the code import the exception from the current layer or the layer below.

PS: don't throw null reference exceptions

oleksii
  • 35,458
  • 16
  • 93
  • 163
  • Many courses and information on the Internet talk about not using exceptions, they talk about create a base class (Result or something similar) and return such information about an error that is easier to handle. – PelikanFix16 Aug 13 '22 at 13:47
  • I think this is bad advice: "put that in the layer that throws those exceptions". Exceptions are a strange kind of return type, so you should be thinking about where the exceptions will be handled/received, and not just where they are thrown. – Christian Davén Jan 09 '23 at 06:59
  • Do not use exceptions as s return type - that's bad advice. You can keep exceptions in the layer that throws them or in other layers, whenever it makes sense – oleksii Jan 09 '23 at 17:40