Bagaimana cara meningkatkan pengecualian di Rails agar berperilaku seperti pengecualian Rails lainnya?

92

Saya ingin meningkatkan pengecualian sehingga itu melakukan hal yang sama seperti pengecualian Rails normal. Secara khusus, tampilkan pengecualian dan pelacakan tumpukan dalam mode pengembangan dan tampilkan halaman "Maaf, ada yang tidak beres" dalam mode produksi.

Saya mencoba yang berikut ini:

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

Tapi itu hanya menulis "ERROR signing up, group missing!"ke file development.log

Chirag Patel
sumber
2
pesan kesalahan yang Anda posting tampaknya tidak berasal dari pengecualian ini (ini adalah pesan yang berbeda) apakah ini yang Anda lihat?
levinalex

Jawaban:

140

Anda tidak perlu melakukan sesuatu yang istimewa, itu seharusnya berhasil.

Ketika saya memiliki aplikasi rel baru dengan pengontrol ini:

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

dan pergi ke http://127.0.0.1:3000/foo/

Saya melihat pengecualian dengan jejak tumpukan.

Anda mungkin tidak melihat seluruh pelacakan tumpukan di log konsol karena Rails (sejak 2.3) memfilter garis dari pelacakan tumpukan yang berasal dari kerangka itu sendiri.

Lihat config/initializers/backtrace_silencers.rbdi proyek Rails Anda

levinalex.dll
sumber
2
Jawaban yang bagus dan ringkas.
rcd
1
Tautan skitch (melihat pengecualian dengan jejak tumpukan) tidak berfungsi lagi
Asaf
@levinalex apakah ini akan aman dalam mode produksi untuk menampilkan stacktrace?
BKSpurgeon
@levinalex - terima kasih alex. apakah ada cara untuk menambahkan string khusus ke pesan kesalahan?
BKSpurgeon
63

Anda bisa melakukannya seperti ini:

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

Apa yang Anda lakukan di sini adalah membuat kelas "NotActivated" yang akan berfungsi sebagai Pengecualian. Dengan menggunakan kenaikan, Anda dapat menampilkan "NotActivated" sebagai Pengecualian. rescue_from adalah cara menangkap Exception dengan metode tertentu (not_activated dalam kasus ini). Contoh yang cukup panjang, tetapi harus menunjukkan cara kerjanya.

Semoga sukses,
Fabian

halfdan
sumber
Ini tidak menunjukkan pengecualian dan pelacakan tumpukan dalam mode pengembangan dan menampilkan halaman "Maaf, tetapi ada yang salah" dalam mode produksi.
Chirag Patel
2
Halaman "kami minta maaf" sebenarnya adalah pengendali kesalahan 500 server web Anda. Periksa file .htaccess Anda dan biasanya Anda akan melihatnya di sana
Jeff Paquette
Mungkin bukan jawaban untuk OP tapi contoh yang sangat berguna, terima kasih!
Neil Stockbridge
12

Jika Anda membutuhkan cara yang lebih mudah untuk melakukannya, dan tidak ingin banyak keributan, eksekusi sederhana dapat berupa:

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

Ini akan menimbulkan pengecualian, katakanlah edengane.message = something bad happened!

dan kemudian Anda dapat menyelamatkannya saat Anda menyelamatkan semua pengecualian lainnya secara umum.

Sambhav Sharma
sumber
Bukan ide yang baik untuk memunculkan atau menyelamatkan 'Exception' itu sendiri, coba gunakan StandardError sebagai gantinya. Lihat ini untuk detailnya: stackoverflow.com/questions/10048173/…
Ekamjit Singh