在我的RAILS控制器中处理第三方API 400/500响应

时间:2017-07-29 11:42:38

标签: ruby-on-rails api fullcontact

我正在学习如何在我的rails应用程序中实现第三方API,但却在努力处理错误响应。

更具体地说,我正在尝试使用gem Full Contact API实现fullcontact-api-ruby。我已经使用我的API Key整理了身份验证,并通过控制台使用gem方法提出了一些请求而没有任何问题。

我现在正在尝试在Profiles Controller中使用API​​包装器方法。我的想法是:

  1. 向控制器发送电子邮件作为参数
  2. Full Contact API方法'person()'将检索与该电子邮件相关的信息
  3. 将创建一个配置文件对象,使用它填充其属性 获取API数据。
  4. 如果该电子邮件没有可用数据, 有一个错误的请求或服务器错误然后一个闪存错误和一个 重定向将会发生。
  5. 我开始编写如下代码:

      # controllers/profiles_controller.rb
      def create
        @intel = FullContact.person(email: params[:email])
        if @intel[:status].to_s[0] != "2"
          flash[:error] = @intel[:status] 
          redirect_to profiles_path
        else
          # Code to create and populate a Profile instance
      end
    

    由于成功响应在200s中有状态代码,我假设我将从Json对象中提取代码并检查它是否以2开头,在这种情况下我将继续创建实例。如果响应正常,这种方法就可以工作,因为我能够处理存储在@intel中的Json对象。但是,当响应在400s时,500s Rails会触发一个异常,导致Rails崩溃而不允许我使用任何JSON对象:

    FullContact::NotFound in ProfilesController#create
    GET https://api.fullcontact.com/v2/person.json?apiKey=MY_API_KEY&email=THE_EMAIL_IM_USING_AS_PARAMETER: 404
    

    我显然做错了什么。我已经尝试避免使用rescue StandardError => e引发的异常,但是我想知道在我的控制器中处理这个错误的正确方法是什么。有什么帮助吗?

    ---更新1尝试转移解决方案 -

    如果我在请求之后拯救例外:

      def create
        @intel = FullContact.person(email: params[:email])
        rescue FullContact::NotFound
    
        if @intel.nil?
          flash[:error] = "Can't process request try again later"
          redirect_to profiles_path
        else
          # Code to create and populate a Profile instance
      end
    

    @intel设置为nil(即未设置为响应JSON对象)。我想我只是更改条件以检查@intel是否为nil但是由于某些奇怪的原因,当响应成功并且@intel设置为JSON对象时,第一个条件不会导致创建对象的方法。即使响应失败,也不确定如何将@intel设置为JSON响应。

2 个答案:

答案 0 :(得分:1)

rescue块的想法是定义从错误中解脱时发生的操作。

构建方法的正确方法是......

def create
  @intel = FullContact.person(email: params[:email])
  # Code to create and populate a Profile instance

rescue FullContact::NotFound   
  flash[:error] = "Can't process request try again later"
  redirect_to profiles_path
end 

在获救后执行rescue后出现的代码,否则将被忽略。

格式为

begin
  # normal code which may or may not encounter a raised error, if no
  #  raised error, it continues to normal completion
rescue 
  # code that is only executed if there was a rescued error
ensure
  # code that always happens, regardless of rescue or not, could be 
  # used to ensure necessary cleanup happens even if an exception raised
end

一种方法本身就是一个完整的begin块,所以在上述格式大纲中不需要beginend

您不需要ensure块,只需添加该块即可显示该功能。还有elserescue一起使用的可能性,但另一天也可以使用{)

答案 1 :(得分:0)

你可以做到

rescue FullContact::NotFound

拯救这个错误。

看起来错误不会让您的比较发生。即便如此,你的比较也是有缺陷的。由于您要将其转换为字符串,因此需要将其与字符串进行比较

更改

   if @intel[:status].to_s[0] != 2

   if @intel[:status].to_s[0] != '2'