【问题标题】:Rails 7 rescue API error and stil show the viewRails 7救援API错误并仍然显示视图
【发布时间】:2022-10-25 03:17:52
【问题描述】:

在我的 Rails 7 应用程序中,我使用了几个 3rd 方 API 来提供获取数据。每次我收到错误时,我都必须 rescuenil 仍然能够将用户重定向到所需的页面,例如:

# lib/custom_api.rb

module CustomApi
  extend self

  def fetch_transactions(user_id)
    client.transactions.list(user_id:)

  # rescue from custom error
  rescue Errors::NotFoundError
    nil
  end
end

# transactions_controller.rb

class TransactionsController < ApplicationController
  def index
    transaction_list = CustomApi.fetch_transactions(current_user.id)

    if transaction_list
      @transactions = transaction_list
    else
      @transactions = transaction_list
      flash[:alert] = 'No transactions'
    end
  end
end

# views/transactions/index.html.erb

<%= turbo_frame_tag 'transactions' do %>
  <%= render partial: 'table_headers' %>
  <%= render Transactions::TableComponent.new(records: @transactions) if @transactions %>
<% end %>

一切正常,但我有 50 个端点需要包含 rescue Errors::NotFoundError,而且我认为重复这条线 50 次是不够的。有没有办法避免这种情况?

【问题讨论】:

  • 你写了:重复这条线50次就足够了.你的意思是什么线?你到底在优化什么?
  • @spickermann 我的意思是rescue Errors::NotFoundError nil
  • 在对我的回答的评论中,您写道您有时会处理 Errors::NotFoundError 而不是返回 nil。当您使用nil 进行救援以及您做一些不同的事情时,是否有一种模式?
  • @spickermann 我有 114 个用于该 API 的端点。处理 NotFoundError 至少有 4 种可能的情况 - 1. 返回 nil 并在控制器内显示一条闪烁消息(我的情况); 2. 显示一则消息和redirect_to request.referrer; 3.redirect_to home; 4. 呼叫外部工人。当然,大小写取决于被调用的端点。

标签: ruby-on-rails ruby


【解决方案1】:

一般来说,使用Rescuable 是Rails 以集中方式从异常中拯救的方式。

将此添加到您的ApplicationController

rescue_from Errors::NotFoundError, with: :handle_not_found_error_from_external_api

private

def handle_not_found_error_from_external_api
  # handle the error in a generalized way, for example, by returning a response
  # that renders a modal or a toast. 
end

并从您的CustomApi 中删除这些行:

# rescue from custom error
rescue Errors::NotFoundError
  nil

【讨论】:

  • 我知道在 ApplicationController 中以集中方式进行救援,但这是两个问题: 1. 将捕获所有 Errors::NotFoundError,即使是它想要处理的那些,而不是返回 nil; 2. 如果我想在索引视图中显示一个空表(为此我需要 transaction_list = nil),这是不可能的,因为这样我会得到空白的 transaction_list 页面。
【解决方案2】:

您可以使用元编程:

module CustomApi
  extend self

  def fetch_resources(resource_type, args)
    send("fetch_#{resource_type}", args)
  # rescue from custom error
  rescue Errors::NotFoundError
    nil
  end

  def fetch_transactions(args)
    client.transactions.list(args)
  end

  def fetch_messages(args)
    # to call this, call CustomApi.fetch_resources(:message, {user_id: current_user.id})
    client.messages.list(args)
  end
end

然后你的控制器将是:

class TransactionsController < ApplicationController
  def index
    @transaction_list = CustomApi.fetch_resources(:transactions, {user_id: current_user.id})
    flash[:alert] = 'No transactions' if @transaction_list.blank?
  end
end

【讨论】:

  • 所以 EOD 我将登陆 50 个班级而不是 1 个模块,里面有 50 个救援?我不明白。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多