Для обработки исключений в Scala, я предпочитаю избежать основной try
/catch
и выгоды от функционального мышления с Validation
от Scalaz (по аналогии с Either
типа в некоторых случаях).Лучший способ написания Scala методы подписи дело с исключениями
Мое приложение предоставляет некоторые услуги. Представьте себе этот метод (не имеющий никакого смысла, но полезного для концепции) в моем сервисе. Он связывает Buyer
(покупатель) с его новым Car
и возвращает Car
, содержащие эту ассоциацию, если все правила прошло с успехом:
def create(carDTO: CarDTO, buyerDTO: BuyerDTO): Validation[Either[TechnicalFailure, List[CarCreationFailure]], CarDTO]
Объяснение: Создание Car
может привести к одному из двух типов исключений:
- Технические сбои (при сбоях баз данных, например) упаковка
Throwable
исключений. - Бизнес-ошибки (правила пользовательского приложения, предотвращающие несоответствие, например,
Car
с незаконным статусом).CarCreationFailure
является одним и, конечно же, может быть продлен болееprecised
сбой.
Мой вопрос особенно акцентирован на стороне клиента и имеет дело с более чем одним потенциалом Business Failure
.
Если тип возвращаемого Validation[Either[TechnicalFailure, List[CarCreationFailure]], CarDTO]
заменяется менее громоздким: ValidationNel[Throwable, CarDTO]
Здесь следует отметить ValidationNel
(накапливающиеся ошибки/исключения в NonEmptyList
).
Недостатком было бы то, что новый читатель не мог, на первый взгляд, предположить, что этот метод возвращает либо TechnicalFailure
, либо CarCreationFailure
(подкласс BusinessFailure
so); просто слишком пугающий Throwable
.
Он будет вынужден применить шаблон, соответствующий каждому Throwable
типам, содержащимся в моем приложении, чтобы быть уверенным, чтобы никто не забыл ... => messy.
Какой самый чистый способ среди этих решений, а может быть ... другой?
Это больше похоже на вопрос «обзор кода», чем вопрос SO. В любом случае, почему бы не создать супертрайт для «TechnicalFailure» и «CarCreationFailures» (который бы обернул «List [CarCreationFailure]»)? Затем система вашего типа знает, что может вернуться, и вы можете сопоставить шаблон, чтобы иметь дело с случаями (и вы можете использовать все в 'Validation'). –
Вы почти _certainly_ не хотите поймать все «Throwable», если вы не пишете что-то вроде контейнера сервлетов. Посмотрите на 'Error' половину' Throwable', спросите себя, действительно ли вы хотите (и можете) обрабатывать все из них. –
Согласитесь с @RexKerr, этот вопрос довольно общий, и трудно дать конкретный ответ. Разумеется, я бы подумал о том, чтобы сменить свой первый тип результата на «ValidationNel [Либо [TechnicalFailure, CarCreationFailure], CarDTO]». –