Отрисовка и повторное повышение исключений в контроллерах Rails - PullRequest
2 голосов
/ 17 января 2012

Я создаю API в Rails и столкнулся с ситуацией, когда я хотел бы предупредить пользователя о том, что случилось что-то плохое, передав ему JSON с сообщением об ошибке.Однако я также хотел бы повторно поднять исключение, чтобы Airbrake (ранее Hoptoad) все еще ловил ошибку и уведомлял нас, чтобы мы могли подробнее разобраться с проблемой.

Я сейчасперехватывает ошибку следующим образом:

begin
  if @myobject.update_attributes(:foo => "bar")
    render :json => @myobject, :status => :ok
  else
    render :json => @myobject.errors, :status => :unprocessable_entity
  end
rescue Exception => e
  render :json => { :errors => { :message => "Uh oh! Something went wrong." } }
  raise e
end

Проблема в том, что мой клиент никогда не получает сообщение JSON, поскольку raise e останавливает его рендеринг и отправляет ему общую ошибку 500.

Какя должен это исправить?

[Мое решение]

Как предложено Джорданом ниже, я просто вызываю notify_airbrake(ex) в своем коде всякий раз, когда я улавливаю исключение.Тем не менее, я немного абстрагировал его, добавив следующее к своему ApplicationController, чтобы в будущем я мог легко переключиться с Airbrake на что-то другое:

class ApplicationController < ActionController::Base
  ...

  def notify_exception_service(ex)
    notify_airbrake(ex)
  end

  ...
end

Итак, вместо notify_airbrake(ex) я просто звоню notify_exception_service(ex).

Ответы [ 2 ]

2 голосов
/ 17 января 2012

Из документации Airbrake gem :

Если вы хотите регистрировать произвольные вещи, которые вы спасли из контроллера, вы можете сделать что-то вроде этого:

rescue => ex
  notify_airbrake(ex)

  flash[:failure] = 'Encryptions could not be rerouted, try again.'
end

Вызов #notify_airbrake отправит уведомление в Airbrake для последующего анализа.В то время как в ваших контроллерах вы используете метод notify_airbrake, в любом другом месте вашего кода используйте Airbrake.notify.

Вам не нужно повторно вызывать исключение вчтобы войти в Airbrake.

2 голосов
/ 17 января 2012

Как я уже говорил в чате, я думаю, вы не можете понять, как рельсы рендерит вещи.Когда вы вызываете render, устанавливается значение @_something_render_variable, но страница не отображается напрямую, все равно есть дополнительный вызов.Вызывая исключение, якобы блокируем этот поток, фактически нарушая рендеринг веб-страницы.

Изменить это поведение действительно сложно, вы должны создать псевдоним метода рендеринга и работать над ним, у меня была похожая проблема.

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