Jak zgłosić wyjątek w Railsach, aby zachowywał się jak inne wyjątki w Railsach?

92

Chciałbym zgłosić wyjątek, aby robił to samo, co normalny wyjątek Rails. W szczególności pokaż wyjątek i ślad stosu w trybie programistycznym i wyświetl stronę „Przepraszamy, ale coś poszło nie tak” w trybie produkcyjnym.

Wypróbowałem następujące:

raise "safety_care group missing!" if group.nil?

Ale po prostu zapisuje "ERROR signing up, group missing!"do pliku development.log

Chirag Patel
źródło
2
opublikowany przez Ciebie komunikat o błędzie nie wydaje się pochodzić z tego wyjątku (jest to inny komunikat), czy to naprawdę jest to, co widzisz?
levinalex

Odpowiedzi:

140

Nie musisz robić nic specjalnego, po prostu powinno działać.

Kiedy mam nową aplikację railsową z tym kontrolerem:

class FooController < ApplicationController
  def index
    raise "error"
  end
end

i idź do http://127.0.0.1:3000/foo/

Widzę wyjątek ze śladem stosu.

Możesz nie zobaczyć całej ścieżki stosu w dzienniku konsoli, ponieważ Railsy (od wersji 2.3) filtrują linie ze śladu stosu, które pochodzą z samego frameworka.

Zobacz config/initializers/backtrace_silencers.rbw swoim projekcie Railsów

levinalex
źródło
2
Doskonała, zwięzła odpowiedź.
rcd
1
Link do skitcha (widząc wyjątek ze śladem stosu) już nie działa
Asaf
@levinalex czy będzie to bezpieczne w trybie produkcyjnym, aby wyświetlić ślad stosu?
BKSpurgeon
@levinalex - dziękuję alex. czy istnieje sposób na dodanie niestandardowego ciągu do komunikatu o błędzie?
BKSpurgeon
63

Możesz to zrobić w ten sposób:

class UsersController < ApplicationController
  ## Exception Handling
  class NotActivated < StandardError
  end

  rescue_from NotActivated, :with => :not_activated

  def not_activated(exception)
    flash[:notice] = "This user is not activated."
    Event.new_event "Exception: #{exception.message}", current_user, request.remote_ip
    redirect_to "/"
  end

  def show
      // Do something that fails..
      raise NotActivated unless @user.is_activated?
  end
end

To, co tutaj robisz, to tworzenie klasy „NotActivate”, która będzie służyć jako wyjątek. Używając podbicia, możesz zgłosić „NotActivated” jako wyjątek. rescue_from to sposób na przechwycenie wyjątku za pomocą określonej metody (w tym przypadku not_activate). Dość długi przykład, ale powinien pokazać, jak to działa.

Najlepsze życzenia,
Fabian

halfdan
źródło
To nie pokazuje wyjątku i śladu stosu w trybie programistycznym i wyświetla stronę „Przepraszamy, ale coś poszło nie tak” w trybie produkcyjnym.
Chirag Patel
2
Strona „przepraszamy” jest w rzeczywistości programem obsługi błędów 500 serwera WWW. Sprawdź swój plik .htaccess, a zazwyczaj go tam zobaczysz
Jeff Paquette,
Może nie jest to odpowiedź na OP, ale bardzo przydatny przykład, dziękuję!
Neil Stockbridge
12

Jeśli potrzebujesz prostszego sposobu, aby to zrobić i nie chcesz zbytniego zamieszania, prostym wykonaniem może być:

raise Exception.new('something bad happened!')

Spowoduje to powstanie wyjątku, powiedzmy eze.message = something bad happened!

a potem możesz go uratować, tak jak ratujesz ogólnie wszystkie inne wyjątki.

Sambhav Sharma
źródło
Nie jest dobrym pomysłem zgłaszanie lub ratowanie samego „wyjątku”, zamiast tego spróbuj użyć StandardError. Zobacz szczegóły: stackoverflow.com/questions/10048173/…
Ekamjit Singh