Где и как обрабатывать исключения для рельсов? - PullRequest
4 голосов
/ 30 июня 2010

В настоящее время я участвую в разработке большого приложения для рельсов, которое взаимодействует с другим продуктом через специальный гем 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 в контроллере?

Лучше ли ловить и обрабатывать исключения в модели, или бросать их в модель и обрабатывать их в контроллере?

1 Ответ

12 голосов
/ 30 июня 2010

Вы ищете rescue_from ?

В вашем контроллере выполните следующие действия:

class MyController < ApplicationController
    rescue_from ActiveRecord::RecordNotFound, :with => :render_missing

    def render_missing
        render 'This is a 404', :status => 404
    end
end

Это будет выполнять метод render_missing каждый раз, когда возникает исключение ActiveRecord::RecordNotFound.
Вы можете использовать его с любым классом исключений, который пожелаете. И вам больше не нужно начинать / спасать свои контроллеры.

Конечно, любое исключение, возникающее в модели, также может быть перехвачено rescue_from.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...