We've already discussed that exceptions are okay to throw from deep within the code for exceptional reasons.
However, there is a class of errors that we do expect from API's. For example, "aggregate not found" which should be translated to a 404 -Not Found response, with an optional reason.
There are many more of these kinds of things, RuleViolation, RoleViolation are two others we could expect frequently.
The question is, what is a reasonable design improvement here (that is an improvement on raising exceptions, and is not to esoteric), for some kind of result type that we could bubble up from the Domain/Application layers that the API layer can translate into HTTP status codes?
We don't want to do this for the hell of it, and certainly not to name any claims about moving more functional.
Solutions
One common solution is to use a Result<TResult> type where you can either return the expected result (including no result) and also return either an exception, and/or some well defined error type.
The error type would have to be good enough to tell the whole story (e.g. code + reason). and we could define some pretty standard ones.
The exception could be there in case you want to raise one. But in general, you would just throw the exception, and the runtime would catch it at the API layer, and convert it to a 500 - Internal Server Error in all cases - since it is unexpected.
What could be another solution?
Problems to avoid
We dont want anything esoteric that is hard to grok for newcomers to it
We dont want to make the code hard to read or understand
We dont want to add far more overhead in testing than we would otherwise
We've already discussed that exceptions are okay to throw from deep within the code for exceptional reasons.
However, there is a class of errors that we do expect from API's. For example, "aggregate not found" which should be translated to a
404 -Not Found
response, with an optional reason.There are many more of these kinds of things,
RuleViolation
,RoleViolation
are two others we could expect frequently.The question is, what is a reasonable design improvement here (that is an improvement on raising exceptions, and is not to esoteric), for some kind of result type that we could bubble up from the Domain/Application layers that the API layer can translate into HTTP status codes?
We don't want to do this for the hell of it, and certainly not to name any claims about moving more functional.
Solutions
One common solution is to use a
Result<TResult>
type where you can either return the expected result (including no result) and also return either an exception, and/or some well defined error type. The error type would have to be good enough to tell the whole story (e.g. code + reason). and we could define some pretty standard ones.The exception could be there in case you want to raise one. But in general, you would just throw the exception, and the runtime would catch it at the API layer, and convert it to a
500 - Internal Server Error
in all cases - since it is unexpected.What could be another solution?
Problems to avoid