Currently, our UseCases can return three different types of response objects:
# A "success" response (e.g. [GetItemLabelsSuccessResponse](https://gerrit.wikimedia.org/g/mediawiki/extensions/Wikibase/+/588a7fd0dba2eda2cd9e34dc60b2a65d9110e1b0/repo/rest-api/src/UseCases/GetItemLabels/GetItemLabelsSuccessResponse.php#10))
# An [ItemRedirectResponse](https://gerrit.wikimedia.org/g/mediawiki/extensions/Wikibase/+/588a7fd0dba2eda2cd9e34dc60b2a65d9110e1b0/repo/rest-api/src/UseCases/ItemRedirectResponse.php#8)
# An [ErrorResponse](https://gerrit.wikimedia.org/g/mediawiki/extensions/Wikibase/+/588a7fd0dba2eda2cd9e34dc60b2a65d9110e1b0/repo/rest-api/src/UseCases/ErrorResponse.php#8) (e.g. [GetItemLabelsErrorResponse](https://gerrit.wikimedia.org/g/mediawiki/extensions/Wikibase/+/588a7fd0dba2eda2cd9e34dc60b2a65d9110e1b0/repo/rest-api/src/UseCases/GetItemLabels/GetItemLabelsErrorResponse.php#13))
While discussing //Chapter 9: Validation// of [Advanced Web Application Architecture](https://matthiasnoback.nl/book/advanced-web-application-architecture/) in our book club, we decided it would be useful to try out **only returning a success response object from a UseCase and throwing an exception in the other situations**.
We perceive that the benefits of throwing exceptions would be:
* The UseCase `execute()` method would only need a single return type instead of union types
* The UseCase `execute()` method would only need a single `return` statement
* In the RouteHandlers, catching different exceptions is nicer than doing several `instanceof` checks in `if`/`elseif`/`else` (or `switch`) statements
* Checks like "is there a validation error", "does the item exist", "is the item a redirect", or "does the user have permission" can be condensed into a few method calls, reducing the number of lines in the UseCase `execute()` method
* It would make it easier to abstract out and reuse the shared logic that is repeated in multiple UseCases
It was left open as to whether we would try this out on existing code (e.g. the `GetItemLabels` UseCase as it is only used be a single RouteHandler) or to try it out on the next endpoint we implement.
---
**Things to consider once a decision has been made:**
- Should we write an ADR explaining our decision?
- Can we abstract some of the shared logic that is repeated in multiple UseCases?