从失败的API调用处理自定义异常代码

时间:2012-06-22 11:07:46

标签: ruby-on-rails ruby-on-rails-3 api httparty

我正在将我们的Rails(3.2)应用程序连接到外部Web服务(活动监视器),这需要对其系统进行几次调用以设置客户端。

我已将每个动作放入单独的救援区并包裹在交易中,但事情看起来并不那么好。我需要它在每次错误后转义并显示正确的消息。目前它刚刚逃脱。

我列出了每个操作可能出现的错误 - 如何读取这些错误并将其格式化为Flash消息?

例如,出现以下错误:

 CreateSend::BadRequest: The CreateSend API responded with the following error - 172: You can create a maximum of five (5) clients per thirty (30) minutes

我目前在我的控制器中有这个:

  def create_send_setup
     ...
      begin

       client = CreateSend::Client.create(@user.company_name, @user.username, @user.email, "(GMT) Dublin, Edinburgh, Lisbon, London", @user.country)

       rescue
        flash[:notice] = "Uh oh, there's been a problem. Please try again. Client"
       end

       begin
         @client = CreateSend::Client.new(@user.createsend_client_api)
         @client.set_access(@user.username, @password, @user.createsend_access_level)
         @client.set_monthly_billing(@user.createsend_currency, true, @user.createsend_markup)

       rescue
          flash[:notice] = "Uh oh, there's been a problem. Please try again. Access"
       end

          flash[:notice] = "Great, now you just need to choose a plan"
          redirect_to edit_user_registration_path    

 end

在之前的整合中,我使用过像

这样的东西
case bla.code.to_s
     when /2../
     when '403'
       raise "Could not update subscriber: new-customer-id is already in use."
     ...
 end

从响应中提取错误代码并显示为flash消息的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

您所能做的就是使用给定的例外 - 如果没有数据有效负载,您可以尝试解析消息字符串,按原样使用,将全部或部分映射到您自己的消息等。

例如,如果您显示的示例消息已规范化,则可以使用正则表达式来获取数字和消息部分:

[1] pry(main)> s = "CreateSend::BadRequest: The CreateSend API responded with the following error - 172: You can create a maximum of five (5) clients per thirty (30) minutes"
=> "CreateSend::BadRequest: The CreateSend API responded with the following error - 172: You can create a maximum of five (5) clients per thirty (30) minutes"
[2] pry(main)> md = s.match /.*?- (\d+): (.*)/
=> #<MatchData
 "CreateSend::BadRequest: The CreateSend API responded with the following error - 172: You can create a maximum of five (5) clients per thirty (30) minutes"
 1:"172"
 2:"You can create a maximum of five (5) clients per thirty (30) minutes">
[3] pry(main)> md[1]
=> "172"
[4] pry(main)> md[2]
=> "You can create a maximum of five (5) clients per thirty (30) minutes"

答案 1 :(得分:1)

正如Dave所说,如果你得到了所有异常,你只能捕获异常,并以字符串的形式对该异常做一些事情。

例如:

begin
  ...
rescue Exception => ex
  # here "ex.message" contains your string, you can do anything you want with it
  # or parse as is:
  flash[:notice] = ex.message
end

redirect_to edit_user_registration_path

<强>更新

如果你将我提出的解决方案与Dave提出的解决方案结合起来,你会得到类似的东西,你可以使用自己的错误字符串:

begin
  ...
rescue Exception => ex
  code = ex.message.match(/.*?- (\d+): (.*)/)[1]

  case code
  when '172'
    flash[:notice] = 'Please wait 30 minutes to create more clients'
  end
end

redirect_to edit_user_registration_path

答案 2 :(得分:1)

在这种特定情况下处理错误的最佳方法是专门处理库自定义的错误。 createsend-ruby定义CreateSendErrorBadRequestUnauthorized。您不需要解析任何字符串。

以下是README处理错误的示例:

require 'createsend'

CreateSend.api_key 'your_api_key'

begin
  cl = CreateSend::Client.new "4a397ccaaa55eb4e6aa1221e1e2d7122"
  id = CreateSend::Campaign.create cl.client_id, "", "", "", "", "", "", "", [], []
  puts "New campaign ID: #{id}"
  rescue CreateSend::BadRequest => br
    puts "Bad request error: #{br}"
    puts "Error Code:    #{br.data.Code}"
    puts "Error Message: #{br.data.Message}"
  rescue Exception => e
    puts "Error: #{e}"
end

data字段始终包含CodeMessage,与status codes API documentation对应。