В настоящее время я участвую в разработке большого приложения для рельсов, которое взаимодействует с другим продуктом через специальный гем API. Это привело к очень странному отлову ошибок. Например, когда мы взаимодействуем с другим продуктом, он может вернуть ошибку аутентификации, которую мы ожидаем. Затем мы фиксируем эту ошибку в нашем геме API и генерируем исключение, которое затем перехватывается и передается пользователю в представлении.
Мне не нравится этот метод перехвата ошибок по нескольким причинам:
- Не похоже, что мы должны ожидать исключений и использовать их в нашей логике. Например, иногда мы хотим перезаписать объект - поэтому мы ловим исключение «объект уже существует» и в любом случае сохраняем нашу модель.
- Требуется много особых ошибок. В коде есть несколько областей, где у нас есть if-elses, которые проверяют определенные ошибки и перенаправляют соответственно.
Тем не менее, я должен конкретизировать гем API, чтобы иметь более простые функции, которые не генерируют исключения? Есть
if user.has_permission_in_product?
if object.doesnt_exist_in_product?
do something
else
redirect somewhere with errors
end
else
redirect somewhere else with errors
end
предпочтительнее
begin
do something
rescue APIError => e
if e.message =~ "no permission"
redirect somewhere with errors
elsif e.message =~ "already exists"
redirect somewhere else with errors
end
end
Кроме того, если первое предпочтительнее, как мы можем справляться с фактическими ошибками API, которые могут появляться в этих функциях? Мы их заполняем в rescue_from в контроллере?
Лучше ли ловить и обрабатывать исключения в модели, или бросать их в модель и обрабатывать их в контроллере?