Wie kann ich eine Ausnahme in Rails auslösen, damit sie sich wie andere Rails-Ausnahmen verhält?

91

Ich möchte eine Ausnahme auslösen, damit sie das Gleiche tut wie eine normale Rails-Ausnahme. Zeigen Sie insbesondere die Ausnahme und den Stack-Trace im Entwicklungsmodus an und zeigen Sie im Produktionsmodus die Seite "Es tut uns leid, aber etwas ist schief gelaufen".

Ich habe folgendes versucht:

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

Aber es schreibt einfach "ERROR signing up, group missing!"in die Datei development.log

Chirag Patel
quelle
2
Die von Ihnen gepostete Fehlermeldung scheint nicht von dieser Ausnahme zu stammen (es ist eine andere Meldung). Ist dies wirklich das, was Sie sehen?
Levinalex

Antworten:

139

Sie müssen nichts Besonderes tun, es sollte einfach funktionieren.

Wenn ich eine neue Rails-App mit diesem Controller habe:

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

und geh zu http://127.0.0.1:3000/foo/

Ich sehe die Ausnahme mit einem Stack-Trace.

Möglicherweise wird nicht die gesamte Stapelverfolgung im Konsolenprotokoll angezeigt, da Rails (seit 2.3) Zeilen aus der Stapelverfolgung filtert, die vom Framework selbst stammen.

Siehe config/initializers/backtrace_silencers.rbin Ihrem Rails-Projekt

Levinalex
quelle
2
Hervorragende, prägnante Antwort.
RCD
1
Die Skitch-Verbindung (die Ausnahme mit einem Stack-Trace zu sehen) funktioniert nicht mehr
Asaf
@levinalex Wird dies im Produktionsmodus sicher sein, um den Stacktrace anzuzeigen?
BKSpurgeon
@levinalex - danke alex. Gibt es eine Möglichkeit, der Fehlermeldung eine benutzerdefinierte Zeichenfolge hinzuzufügen?
BKSpurgeon
62

Sie können es so machen:

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

Was Sie hier tun, ist das Erstellen einer Klasse "NotActivated", die als Ausnahme dient. Mit Raise können Sie "NotActivated" als Ausnahme auslösen. Rescue_from ist die Methode zum Abfangen einer Ausnahme mit einer angegebenen Methode (in diesem Fall nicht aktiviert). Ein ziemlich langes Beispiel, aber es sollte Ihnen zeigen, wie es funktioniert.

Beste Grüße,
Fabian

Halfdan
quelle
Dies zeigt nicht die Ausnahme und den Stack-Trace im Entwicklungsmodus und die Seite "Es tut uns leid, aber etwas ist schief gelaufen" im Produktionsmodus.
Chirag Patel
2
Die Seite "Es tut uns leid" ist der 500-Fehler-Handler Ihres Webservers. Überprüfen Sie Ihre .htaccess-Datei und Sie werden sie normalerweise dort sehen
Jeff Paquette
Vielleicht keine Antwort auf das OP, aber ein sehr nützliches Beispiel, danke!
Neil Stockbridge
11

Wenn Sie einen einfacheren Weg benötigen und nicht viel Aufhebens machen möchten, könnte eine einfache Ausführung sein:

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

Dies wird eine Ausnahme auslösen, beispielsweise emite.message = something bad happened!

und dann können Sie es retten, während Sie alle anderen Ausnahmen im Allgemeinen retten.

Sambhav Sharma
quelle
Es ist keine gute Idee, 'Exception' selbst auszulösen oder zu retten. Versuchen Sie stattdessen, StandardError zu verwenden. Weitere Informationen finden Sie hier: stackoverflow.com/questions/10048173/…
Ekamjit Singh