如何在 Rails 中引发异常,使其表现得像其他 Rails 异常?

Posted

技术标签:

【中文标题】如何在 Rails 中引发异常,使其表现得像其他 Rails 异常?【英文标题】:How do I raise an exception in Rails so it behaves like other Rails exceptions? 【发布时间】:2010-12-27 11:08:30 【问题描述】:

我想引发一个异常,以便它执行与普通 Rails 异常相同的操作。特别是,在开发模式下显示异常和堆栈跟踪,在生产模式下显示“我们很抱歉,但出了点问题”页面。

我尝试了以下方法:

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

但它只是将"ERROR signing up, group missing!" 写入 development.log 文件

【问题讨论】:

您发布的错误消息似乎不是来自此异常(这是一条不同的消息),这真的是您所看到的吗? 【参考方案1】:

您不必做任何特别的事情,它应该可以正常工作。

当我有一个新的带有这个控制器的 Rails 应用程序时:

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

然后转到http://127.0.0.1:3000/foo/

我看到堆栈跟踪异常。

您可能不会在控制台日志中看到整个堆栈跟踪,因为 Rails(自 2.3 起)filters lines from the stack trace that come from the framework itself.

在 Rails 项目中查看 config/initializers/backtrace_silencers.rb

【讨论】:

优秀,简洁的答案。 skitch 链接(通过堆栈跟踪查看异常)不再起作用 @levinalex 在生产模式下显示堆栈跟踪是否安全? @levinalex - 谢谢亚历克斯。有没有办法在错误消息中添加自定义字符串?【参考方案2】:

如果您需要一种更简单的方法,并且不想大惊小怪,那么简单的执行可以是:

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

这将引发异常,例如 ee.message = something bad happened!

然后你可以像拯救所有其他异常一样拯救它。

【讨论】:

引发或挽救“异常”本身不是一个好主意,请尝试使用 StandardError。详情请见:***.com/questions/10048173/…【参考方案3】:

你可以这样做:

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

您在这里所做的是创建一个用作异常的类“NotActivated”。使用 raise,您可以将“NotActivated”作为异常抛出。 rescue_from 是使用指定方法(在本例中为 not_activated)捕获 Exception 的方式。一个相当长的例子,但它应该向您展示它是如何工作的。

最好的祝愿, 费边

【讨论】:

这在开发模式下不显示异常和堆栈跟踪,在生产模式下显示“我们很抱歉,但出现问题”页面。 “我们很抱歉”页面实际上是您的 Web 服务器的 500 错误处理程序。检查你的 .htaccess 文件,你通常会在那里看到它 也许不是对 OP 的回答,而是一个非常有用的例子,谢谢!

以上是关于如何在 Rails 中引发异常,使其表现得像其他 Rails 异常?的主要内容,如果未能解决你的问题,请参考以下文章

当它应该表现得像 try/catch/finally 时,为啥使用会抛出异常?

如何在 Rails/RSpec 中测试异常引发?

`lazy val` 在异常情况下表现得像 `def` 是正确的行为吗?

Rails 4, RSpec 3.2 - 如何模拟 ActionMailer 的 Deliver_now 方法来引发异常

如何让数据网格表现得像 ctrl 键处于活动状态?

如何使 Material UI 图标表现得像锚标签?