【发布时间】:2023-03-07 00:45:01
【问题描述】:
我在这里有一个非常基本的应用程序,我试图通过将一个类声明为该错误来更明显地产生错误和异常。有问题的课程是InvalidUserId,它取代了Sequel::DatabaseError
在主应用程序逻辑中,我尝试使用self[:address] 通过id 从数据库中获取用户。因为这是一种验证方法,所以输入不一定是id,而是一个电子邮件地址,这会导致模型以Sequel::DatabaseError 失败。
这很好,花花公子,但我的救援声明似乎没有认识到InvalidUserId 指向Sequel::DatabaseError,这意味着当发生该错误时,代码不会进入rescue 块。但是,如果我将救援中的 InvalidUserId 替换为 Sequel::DatabaseError,它确实会进入救援块。
module SomeModule
class InvalidUserId < Sequel::DatabaseError; end
..
def validate
if this_criteria_is_satisfied?
begin
user = App::Model::User.where(id: self[:address]).first
if user.nil?
raise InvalidUserId
end
rescue InvalidUserId # won't step into this block if I use this class.
# But will step into the rescue block if I
# use Sequel::DatabaseError
errors.add(:address, "Specified user (#{self[:address]}) is not valid. (code: invalid)")
return
end
end
end
我不确定为什么应用程序无法识别我的自定义错误,即使抛出的错误是我声明的错误。
编辑:似乎这种制作自定义异常的方法只允许您引发而不是捕获,对吗?
【问题讨论】:
-
你确定你是成功加注的吗?如果它真的被提出了,这段代码应该会捕捉到它,尽管值得注意的是,这确实不是在本地层次上构建这个逻辑的方法。
-
raise行工作得很好。rescue部分似乎没有捕获user = App::Model::User.where(id: self[:address]).first,当它因该异常而失败时 -
我在问
raise行是否真的会触发,因为我怀疑它不会触发。您可能会在引发异常并跳过它之前生成另一个错误。尝试注释掉你的user =代码加上if并每次都提出它。 -
我刚刚注释掉了
user这一行以及if语句,是的,它成功引发了。 -
问题是不是救援失败。问题在于:
App::Model::User.where(id: self[:address])是引发错误的原因,而该错误不是InvalidUserId的实例。为了实现这一点,唯一明智的方法是重新引发所需类的错误。 (这是否是一个好主意是另一个问题......)
标签: ruby class exception sequel