如何在Rails中为404响应添加错误消息?

huangapple go评论60阅读模式
英文:

How can I add an error message to response for 404 in rails?

问题

我需要为404错误的响应添加错误消息。
我在控制器中有一些方法:

def method
    *一些逻辑*

    if something.present?
      render json: something, serializer: SomeSerializer
    else
      render json: { errors: I18n.t('errors.something.no_something') }, status: :not_found
    end
  end

但当我通过Postman发出请求时,项目的404页面显示出来,没有错误输出。

我如何显示特定的错误消息?

英文:

I need to add an error message to response for 404 error.
I have some method in controller:

def method
    *some logic*

    if something.present?
      render json: something, serializer: SomeSerializer
    else
      render json: { errors: I18n.t('errors.something.no_something') }, status: :not_found
    end
  end

But when I make a request via postman, the 404 page of the project is shown, without an error output

How can I show a specific error?

答案1

得分: 4

Ruby on Rails在特定异常被引发时会自动返回默认的404未找到错误页面,例如ActionController::RoutingErrorActiveRecord::RecordNotFound

在你的代码示例和描述中,很可能在实际达到if something.present?条件之前,已经引发了ActiveRecord::RecordNotFound异常。

一个简单的解决方案可能是捕获该异常并在控制器方法中返回你的自定义错误消息,如下所示:

def method
  # 一些逻辑
  
  render json: something, serializer: SomeSerializer
rescue ActiveRecord::RecordNotFound
  render json: { errors: I18n.t('errors.something.no_something') }, status: :not_found
end

另一个选项是以不引发ActiveRecord::RecordNotFound异常的方式从数据库加载记录,而是自己处理找不到记录的情况。

这取决于你的具体代码(你没有分享),可能会像这样:

something = Something.find(params[:id]) # 当未找到时引发异常

然后你可以将它改为:

```ruby
something = Something.find_by(id: params[:id]) # 未找到时返回nil

if something.present?
  render json: something, serializer: SomeSerializer
else
  render json: { errors: I18n.t('errors.something.no_something') }, status: :not_found
end
英文:

Ruby on Rails returns the default 404 not found error page automatically when specific exceptions are raised, for example, ActionController::RoutingError or ActiveRecord::RecordNotFound.

In your code example and with your description, it is likely that an ActiveRecord::RecordNotFound was already raised somewhere in the code before you actually reached the if something.present? condition.

A simple solution might be to rescue from that exception and return your custom error message in the controller method, like this:

def method
  *some logic*
  
  render json: something, serializer: SomeSerializer
rescue ActiveRecord::RecordNotFound
  render json: { errors: I18n.t('errors.something.no_something') }, status: :not_found
end

end

Another option would be to load records from the database in a way that doesn't raise ActiveRecord::RecordNotFound exception when not found, and instead handle missing records on your own.

What that might look like depends, of course, on your specific code (that you didn't share). If you had code like this:

something = Something.find(params[:id]) # raises exception when not found

then you could change it to:

something = Something.find_by(id: params[:id]) # returns nil when not found

if something.present?
  render json: something, serializer: SomeSerializer
else
  render json: { errors: I18n.t('errors.something.no_something') }, status: :not_found
end

huangapple
  • 本文由 发表于 2023年6月8日 15:28:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76429550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定