Làm cách nào để nêu ra một ngoại lệ trong Rails để nó hoạt động giống như các ngoại lệ Rails khác?


91

Tôi muốn nêu ra một ngoại lệ để nó thực hiện điều tương tự như một ngoại lệ Rails bình thường. Đặc biệt, hiển thị ngoại lệ và dấu vết ngăn xếp trong chế độ phát triển và hiển thị trang "Chúng tôi xin lỗi, nhưng đã xảy ra lỗi" trong chế độ sản xuất.

Tôi đã thử những cách sau:

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

Nhưng nó chỉ đơn giản là ghi "ERROR signing up, group missing!"vào tệp development.log


2
thông báo lỗi bạn đã đăng dường như không đến từ ngoại lệ này (đó là một thông báo khác) đây có thực sự là những gì bạn đang thấy không?
levinalex

Câu trả lời:


139

Bạn không cần phải làm bất cứ điều gì đặc biệt, nó chỉ nên hoạt động.

Khi tôi có một ứng dụng đường ray mới với bộ điều khiển này:

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

và đi đến http://127.0.0.1:3000/foo/

Tôi thấy ngoại lệ với dấu vết ngăn xếp.

Bạn có thể không thấy toàn bộ dấu vết ngăn xếp trong nhật ký bảng điều khiển vì Rails (kể từ 2.3) lọc các dòng khỏi dấu vết ngăn xếp đến từ chính khuôn khổ.

Xem config/initializers/backtrace_silencers.rbtrong dự án Rails của bạn


2
Câu trả lời ngắn gọn, xuất sắc.
rcd

1
Các liên kết Skitch (nhìn thấy những ngoại lệ với một stack trace) không hoạt động nữa
Asaf

@levinalex sẽ an toàn trong chế độ sản xuất để hiển thị stacktrace?
BKSpurgeon

@levinalex - cảm ơn bạn alex. có cách nào để thêm một chuỗi tùy chỉnh vào thông báo lỗi không?
BKSpurgeon

62

Bạn có thể làm như thế này:

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

Những gì bạn đang làm ở đây là tạo một lớp "Không kích hoạt" sẽ đóng vai trò là Ngoại lệ. Bằng cách sử dụng tăng, bạn có thể ném "NotActiised" làm Ngoại lệ. Rescue_from là cách bắt một Ngoại lệ với một phương thức được chỉ định (not_actiised trong trường hợp này). Một ví dụ khá dài, nhưng nó sẽ cho bạn thấy nó hoạt động như thế nào.

Những lời chúc tốt đẹp nhất,
Fabian


Điều này không hiển thị ngoại lệ và dấu vết ngăn xếp trong chế độ phát triển và hiển thị trang "Chúng tôi xin lỗi, đã xảy ra lỗi" trong chế độ sản xuất.
Chirag Patel

2
Trang "chúng tôi xin lỗi" thực sự là trình xử lý lỗi 500 của máy chủ web của bạn. Kiểm tra tập tin .htaccess của bạn và bạn thường sẽ thấy nó ở đó
Jeff Paquette

Có thể không phải là câu trả lời cho OP nhưng là một ví dụ rất hữu ích, cảm ơn bạn!
Neil Stockbridge

11

Nếu bạn cần một cách dễ dàng hơn để làm điều đó và không muốn phiền phức, một cách thực hiện đơn giản có thể là:

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

Điều này sẽ đưa ra một ngoại lệ, giả sử evớie.message = something bad happened!

và sau đó bạn có thể giải cứu nó vì bạn đang giải cứu tất cả các trường hợp ngoại lệ khác nói chung.


Không phải là một ý kiến ​​hay khi tự nâng cấp hoặc giải cứu 'Exception', hãy thử sử dụng StandardError để thay thế. Xem điều này để biết chi tiết: stackoverflow.com/questions/10048173/…
Ekamjit Singh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.