这是一个简单的应用程序:
class App < Sinatra::Base
set :show_exceptions, false
not_found do
slim :err_404
end
post "/doit" do
user ||= User.find(params["userid"]) || halt(404)
end
end
当给出无效的用户ID时,404错误块应该触发然后呈现404页面。相反,Sinatra在页面上显示“Internal Server Error
”,并且此堆栈跟踪将打印到控制台:
Problem:
Document(s) not found for class User with id(s) 53d06a8ca7b7d52d11300003.
Summary:
....
我猜测halt(404)
没有被调用。我正在关注这个blog post about error handling,那为什么同样的事情不会在这里发挥作用呢?
答案 0 :(得分:2)
假设您正在使用ActiveRecord,如果没有匹配的记录,User.find(params["userid"])
将引发ActiveRecord::RecordNotFound
异常。在404处理程序运行并结束路由处理之前抛出此异常,从而导致内部服务器错误。
要修复它,你可以检查异常,如果它被引发则调用404处理程序:
post "/doit" do
begin
user ||= User.find(params["userid"]
rescue ActiveRecord::RecordNotFound
halt(404)
end
end
更好的解决方案可能是使用find_by_id
代替,这可以避免使用流控制的异常:
post "/doit" do
user ||= User.find_by_id(params["userid"]) || halt(404)
end