gpt4 book ai didi

ruby-on-rails - 如何定义rescue_from后备处理程序?

转载 作者:行者123 更新时间:2023-12-01 19:21:28 24 4
gpt4 key购买 nike

我有一个异常处理程序模块,我将其包含在 Controller 中以捕获各种 Rails 错误:

module ExceptionHandler
# provides the more graceful `included` method
extend ActiveSupport::Concern

included do
rescue_from ActiveRecord::RecordNotFound do |e|
render json: { message: e.message }, status: :not_found
logger.error(e.message)
end

rescue_from ActionController::ParameterMissing do |e|
logger.error(e.message)
render json: {
message: "Parameter missing",
details: e.message,
parameter: e.param
}, status: :bad_request
end

rescue_from ActiveRecord::RecordInvalid do |e|
logger.error(e.message)
render json: {
attributes: e.record.errors.messages.keys,
message: "Invalid record",
details: e.record.errors.messages,
}, status: :unprocessable_entity
end

rescue_from ActionController::RoutingError do |e|
logger.error(e.message)
render json: { message: e.message }, status: :not_found
end
end
end

但是,这只能捕获我定义的特定错误。当我遇到其他错误时,我会从 Rails 收到 JSON 响应,其中包含非常详细的消息、堆栈跟踪等。

我想至少在生产中防止这种情况发生,并且只以我自己的格式返回 500 错误。

我已阅读 posts like this但它们不包括标准错误的“后备”选项。因此,我尝试天真地添加一个 rescue_from StandardError,但这似乎优先于我定义的所有其他错误。

我想我可以拯救 StandardError,然后从那里进行大小写切换,但这似乎是一个黑客:

  included do
rescue_from StandardError do |e|
# TPDP_ better öpggomg
logger.error(e.message)
handle_error(e)
end
end

处理这个问题的正确方法是什么?

最佳答案

我解决这个问题的方法是使用我的应用程序 Controller 中包含的异常处理程序问题。

在 Controller 中:

class MyController < ApplicationController
include ExceptionHandler
end

以及处理程序exception_handler.rb:

module ExceptionHandler
extend ActiveSupport::Concern

ERROR_MAP = {
ActionController::RoutingError => {
method: :record_not_found,
status: :not_found
},
ActiveRecord::RecordNotFound => {
method: :record_not_found,
status: :not_found
},
ActionController::ParameterMissing => {
method: :parameter_missing,
status: :unprocessable_entity
},
ActiveRecord::RecordInvalid => {
method: :record_invalid,
status: :unprocessable_entity
}
}.freeze

included do
rescue_from StandardError do |e|
logger.error(e.message)
handle_error(e)
end
end

private

def handle_error(e)
# byebug
if ERROR_MAP.keys.include? e.class
handler = ERROR_MAP[e.class]
body = send(handler[:method], e)
status = handler[:status]
else
# fallback variant: error 500
body = {
message: "General server error"
}
status = 500
end

render json: body, status: status
end

# Define the return bodies here, per error type

def record_not_found(e)
{
message: "Not found",
details: e.message
}
end

def parameter_missing(e)
{
message: "Parameter missing",
details: e.message,
parameter: e.param
}
end

def record_invalid(e)
{
model: e.record.class.name,
attributes: e.record.errors.messages.keys,
message: "Invalid record",
details: e.record.errors.messages
}
end
end

显然,您可以添加应捕获的其他错误,并定义应发送的状态。

关于ruby-on-rails - 如何定义rescue_from后备处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58378691/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com