From b7338ad1dcb2f162f2ec2ac7cc80ea9d903ccae1 Mon Sep 17 00:00:00 2001 From: Tyler Rick Date: Mon, 17 Oct 2016 11:56:33 -0700 Subject: [PATCH] Pass on any specific error message returned from Mailgun When the Mailgun API returns a "400 Bad Request" error, it includes the specific error message (for example, "'to' parameter is missing") from in the JSON response. However, there was no easy way to see what that specific error message actually was, and you'd end up with a generic (and therefore useless) RestClient::BadRequest error from your Rails app that you had no idea the actual cause of. This change causes it to automatically extract that specific message from the JSON response and use that as the Ruby exception message. --- lib/mailgun_rails/deliverer.rb | 8 +++++++- spec/lib/mailgun_rails/deliverer_spec.rb | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/mailgun_rails/deliverer.rb b/lib/mailgun_rails/deliverer.rb index ddf073c..736a63f 100644 --- a/lib/mailgun_rails/deliverer.rb +++ b/lib/mailgun_rails/deliverer.rb @@ -21,7 +21,13 @@ def verify_ssl end def deliver!(rails_message) - response = mailgun_client.send_message build_mailgun_message_for(rails_message) + begin + response = mailgun_client.send_message build_mailgun_message_for(rails_message) + rescue RestClient::Exception => mailgun_error + json = JSON.parse(mailgun_error.http_body.to_s) rescue raise(mailgun_error) + mailgun_error.define_singleton_method(:message) { json["message"] } + raise mailgun_error + end if response.code == 200 mailgun_message_id = JSON.parse(response.to_str)["id"] rails_message.message_id = mailgun_message_id diff --git a/spec/lib/mailgun_rails/deliverer_spec.rb b/spec/lib/mailgun_rails/deliverer_spec.rb index 892469f..f617f79 100644 --- a/spec/lib/mailgun_rails/deliverer_spec.rb +++ b/spec/lib/mailgun_rails/deliverer_spec.rb @@ -115,12 +115,30 @@ msg.message_id.should eq "20111114174239.25659.5817@samples.mailgun.org" end + it "should include the error message returned from Mailgun in the Ruby exception message" do + msg = Mail::Message.new(to: [], cc: 'cc@email.com', from: 'from@email.com') + expectation = { to: [], cc: ['cc@email.com'], from: ['from@email.com']} + check_mailgun_error msg, expectation, RestClient::BadRequest, "'to' parameter is missing" + end + def check_mailgun_message(rails_message, mailgun_message) rest_response = double(:code => 200, :to_str => '{"message": "Queued. Thank you.","id": "<20111114174239.25659.5817@samples.mailgun.org>"}') mailgun_client.should_receive(:send_message).with(mailgun_message).and_return(rest_response) MailgunRails::Deliverer.new(api_key: api_key, domain: domain).deliver!(rails_message) end + def check_mailgun_error(rails_message, mailgun_message, exception, message) + body = %{{"message": #{JSON.dump message}}} + response = double(code: 400, body: body) + exception = exception.new(response) + allow(mailgun_client).to receive(:send_message).and_raise(exception) + expect { + MailgunRails::Deliverer.new(api_key: api_key, domain: domain).deliver!(rails_message) + }.to raise_exception(RestClient::BadRequest) {|exception| + expect(exception.message).to eq message + } + end + def rails_message_with_attachment msg = basic_multipart_rails_message msg.attachments["attachment.jpg"] = "\312\213\254\232"