Reputation: 2804
I'm connecting our Rails (3.2) application to an external web service (campaign monitor) which requires a few calls to their system to set a client up.
I've put each action into separate rescue blocks and wrapped in a transaction but things aren't looking so great. I need it to escape after each error and display the correct message. Currently it just escapes.
I have a list of possible errors per action - how is it possible to read these and format as a flash message?
For example, the following error:
CreateSend::BadRequest: The CreateSend API responded with the following error - 172: You can create a maximum of five (5) clients per thirty (30) minutes
I currently have this in my controller:
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
In a previous integration, I've used something like
case bla.code.to_s
when /2../
when '403'
raise "Could not update subscriber: new-customer-id is already in use."
...
end
What's the best way to extract the error code from the response and display as a flash message?
Upvotes: 1
Views: 1469
Reputation: 51
The best way of handling errors in this specific situation is by specifically handing the errors which the library defines itself. createsend-ruby defines CreateSendError, BadRequest, and Unauthorized. You do not need to parse any strings.
Here is an example take from the README, of handling errors:
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
The data
field always contains a Code
and Message
, which correspond to the status codes API documentation.
Upvotes: 1
Reputation: 2270
As Dave said, if the exception is all you've got, you can only capture the exception and do something with that exception as a string.
For example:
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
UPDATE
If you combine my proposed solution with those put forward by Dave, you'd get something like this, with which you can use your own error strings:
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
Upvotes: 1
Reputation: 160191
All you can do is work with the exception given-if there's no data payload you can try to parse the message strings, use it as-is, map all or part of it to your own messages, etc.
For example, if the example message you show is normalized, a regex could be used to grab the numeric and message portions:
[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"
Upvotes: 2