简体   繁体   English

将“渲染”键从“普通”更改为“json”会导致服务器错误

[英]Changing "render" key from "plain" to "json" causes server error

Consider the following code考虑以下代码

class AuthenticatedController < ApplicationController
  rescue_from InvalidCredentials, with: :unauthenticated

  def current_user
    raise InvalidCredentials
  end

  private

  def unauthenticated(_error)
    render plain: { error: 'text' }.to_json, status: :unauthorized
  end
end

class UsersController < AuthenticatedController
  def show
    render json: current_user
  end
end

When I request Users#show it renders {"error":"text"} just fine.当我请求 Users#show 它呈现{"error":"text"}就好了。

But if I change unauthenticated to但是,如果我将unauthenticated身份验证的更改为

  def unauthenticated(_error)
    render json: { error: 'text' }, status: :unauthorized
  end

And the resource responds with {"status":500,"error":"Internal Server Error"} .并且资源响应{"status":500,"error":"Internal Server Error"}

The stack trace:堆栈跟踪:

Started GET "/api/v1/user" for ::1 at 2021-08-25 12:24:30 +0300
Processing by Api::V1::UsersController#show as JSON
  Parameters: {"user"=>{}}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms | Allocations: 214)

InvalidCredentials (InvalidCredentials):
app/controllers/users_controller.rb:in `show'
app/controllers/authenticated_controller.rb:in `current_user'
app/controllers/authenticated_controller.rb:in `unauthenticated'

So calling render json: {} in the handler causes the same error to be raised again.因此在处理程序中调用render json: {}会导致再次引发相同的错误。 But at the same time render plain: '' does not.但同时render plain: ''不会。

What happens when I change key from plain to json and how to make it respond with :unauthorized instead of server error when using JSON?当我将密钥从plain密钥更改为json时会发生什么,以及如何使其在使用 JSON 时以:unauthorized而不是服务器错误响应?

I was using active_model_serializers library for rendering JSON. It uses scope option of render as a method name to invoke and it is current_user by default .我正在使用active_model_serializers库来呈现 JSON。它使用scope render选项作为要调用的方法名称,默认情况下current_user So the library invoked current_user method again when I called render json: ... leading to the error.因此,当我调用render json: ...时,库再次调用current_user方法,导致错误。

I've changed unauthenticated method to我已将未经身份unauthenticated的方法更改为

  def unauthenticated(_error)
    render json: { error: 'text' }, status: :unauthorized, scope: nil
  end

and it began to work as expected.它开始按预期工作。

Based on the information you have given, the problem is most likely how you use rescue_from The request which triggers the error have to be a JSON request in order for this to work.根据您提供的信息,问题很可能是您如何使用rescue_from触发错误的请求必须是 JSON 请求才能使其正常工作。 For example if you try to login from a form it's usually by default a HTMl request.例如,如果您尝试从表单登录,默认情况下通常是 HTMl 请求。 A way to confirm this is to use raise request.inspect in the controller method.确认这一点的一种方法是在 controller 方法中使用raise request.inspect If this is the case, there is no easy fix and you will have to fix the request it self or just support both.如果是这种情况,则没有简单的修复方法,您将不得不自行修复请求或同时支持两者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM