0

So far I have this...

class MembersController < ApplicationController

  rescue_from Mailchimp::Exception::DataException,
    Mailchimp::Exception::APIKeyError,
    Mailchimp::Exception::NotFound,
    Mailchimp::Exception::Duplicate,
    Mailchimp::Exception::MissingField,
    Mailchimp::Exception::BadRequest,
    Mailchimp::Exception::UnknownAttribute,
    Mailchimp::Exception::MissingId,
    with: :error

  def error(e)

    puts 'Message: ' + e.message
    puts 'Type: ' + e.type
    puts 'Title: ' + e.title

    e.errors.each do |error|
      puts 'Field: ' + error['field']
      puts 'Message: ' + error['message']
    end if e.errors

    # Respond to the HTTP POST request by passing the errors
    return render_with(500, e.message, e.errors)

  end

  private

  def render_with(status_code, message, errors='none')

    if errors == 'none'
      status = 'success'
      success = true
    else
      status = 'error'
      success = false
    end

    render json: {
      :status => status,
      :success => success,
      :message => message,
      :errors => errors,
      :params => params.as_json
    },
    status: status_code

  end

end

In an attempt to make it DRY, I have done this...

class MembersController < ApplicationController

  mailchimpExceptions = [
    'DataException',
    'APIKeyError',
    'NotFound',
    'Duplicate',
    'MissingField',
    'BadRequest',
    'UnknownAttribute',
    'MissingId'
  ]

  exceptions = Array.new

  mailchimpExceptions.each do |exception|
    exceptions << "Mailchimp::Exception::#{exception}"
  end

  rescue_from *exceptions, with: :error

  def error(e)

    puts 'Message: ' + e.message
    puts 'Type: ' + e.type
    puts 'Title: ' + e.title

    e.errors.each do |error|
      puts 'Field: ' + error['field']
      puts 'Message: ' + error['message']
    end if e.errors

    # Respond to the HTTP POST request by passing the errors
    return render_with(500, e.message, e.errors)

  end

  private

  def render_with(status_code, message, errors='none')

    if errors == 'none'
      status = 'success'
      success = true
    else
      status = 'error'
      success = false
    end

    render json: {
      :status => status,
      :success => success,
      :message => message,
      :errors => errors,
      :params => params.as_json
    },
    status: status_code

  end

end

I am wondering if all the exceptions could by under one class, so that only one class is called like rescue_from MailchimpExceptions, with: :error. This answer by mgolubitsky suggests it is possible, but I have no idea how to go about it.

I am using gem 'mailchimp_api_v3'.

Community
  • 1
  • 1
ckhatton
  • 1,359
  • 1
  • 14
  • 43

2 Answers2

2

Take a look at https://github.com/dominicsayers/mailchimp_api_v3#exception-handling

It says:

All exceptions will be subclasses of Mailchimp::Exception

try rescue_from Mailchimp::Exception, with: :error

thaleshcv
  • 752
  • 3
  • 7
  • I'm afraid that doesn't work - It doesn't rescue the exception. I seem to remember trying that before, as I also read that line in the README.md – ckhatton Mar 15 '17 at 11:20
2

I have no idea about mailchimp itself, but I can generally suggest how to make it DRY properly:

EXCEPTIONS = %w|
  DataException
  APIKeyError
  NotFound
  Duplicate
  MissingField
  BadRequest
  UnknownAttribute
  MissingId|.map { |e| Mailchimp::Exception.const_get(e) }

rescue_from *EXCEPTIONS, with: :error

Or, to rescue_from all exceptions, defined in Mailchimp::Exception at once:

EXCEPTIONS = Mailchimp::Exception.constants.map do |e|
  Mailchimp::Exception.const_get(e)
end.select { |e| e.is_a?(Class) && e < Exception }
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • Real tidy! Like it! Though the latter didn't work, I think because of an error on this [gem page](https://github.com/dominicsayers/mailchimp_api_v3/blob/develop/lib/mailchimp_api_v3/exception.rb) `ArgumentError ({"RestClient::ResourceNotFound"=>Mailchimp::Exception::NotFound, "RestClient::Unauthorized"=>Mailchimp::Exception::APIKeyError} must be an Exception class or a String referencing an Exception class):` – ckhatton Mar 15 '17 at 11:38
  • Simply filter out everything that is not an exception. I have the answer updated. – Aleksei Matiushkin Mar 15 '17 at 13:20
  • That doesn't pick up anything - In other words, it produced an empty array – ckhatton Mar 15 '17 at 14:01
  • Oh, indeed. `e` is a class there, not instance, please see an update. – Aleksei Matiushkin Mar 15 '17 at 14:03
  • Now `TypeError (no implicit conversion of Class into Hash):`. Maybe the Class name needs to be grabbed as a string? – ckhatton Mar 15 '17 at 15:42
  • I blindly try to guess how mailchimp constants look like, while you have it on hand. OK, not I am sure it will work as expected. – Aleksei Matiushkin Mar 15 '17 at 15:47
  • I think what you are after is instances, not constants. [This the class in which you are looking in](https://github.com/dominicsayers/mailchimp_api_v3/blob/develop/lib/mailchimp_api_v3/exception.rb) – ckhatton Mar 15 '17 at 16:01