Home > Enterprise >  How can I render a ruby on rails .erb template if something being fetched from an external api retur
How can I render a ruby on rails .erb template if something being fetched from an external api retur

Time:01-06

I have an admin page where I can change a users email template. Right now MailChimp/Mandrill is having outages and it is crashing my app.

This is the line that crashes the page, when I comment it out it loads the page fine

<%= render 'super_admin/shared/select', f: f, what: :email_template_name, collection: MandrillWrapper.template_names %>

The log when it crashes shows

17:25:06 dev.1  | Mandrill::Error (We received an unexpected error: <html>
17:25:06 dev.1  | <head><title>502 Bad Gateway</title></head>
17:25:06 dev.1  | <body bgcolor="white">
17:25:06 dev.1  | <center><h1>502 Bad Gateway</h1></center>
17:25:06 dev.1  | <hr><center>nginx/1.12.2</center>
17:25:06 dev.1  | </body>
17:25:06 dev.1  | </html>
17:25:06 dev.1  | ):

So I know it is Mandrill and I checked and they have outages right now.

I've tried

<% if MandrillWrapper.template_names.present? %>
<%= render 'super_admin/shared/select', f: f, what: :email_template_name, collection: MandrillWrapper.template_names %>
    <% else %>
    <p>templates currently unavailable</p>
  <% end %>

and

<% begin %>
<%= render 'super_admin/shared/select', f: f, what: :email_template_name, collection: MandrillWrapper.template_names %\>
<% rescue %>
<p>templates currently unavailable</p>
<% end %>

CodePudding user response:

Based on your description, the MandrillWrapper.template_names is making an external API or other call that fails.

First, I would move the external call to the controller where I could handle the error correctly and then pass whatever is appropriate to the views to either show the email templates to be modified or some message telling the user to try again some time later. Handling the external call in a controller action allows it to be tested more easily than in the views.

As the second step to improve the code, I would move the handling of the external call to a service or presenter object that the controller action would call. Again, this would make testing the handling so much easier.

Finally as a third improvement step, you might be able to "automate" or schedule the external call by moving it to a background job so that you wouldn't have to make the call at all at the time when the controller action is run but before it. You would have to store something in the database for this but this would make rendering the page much faster and again simplify testing.

Whether the last step is possible for you depends on many things about your business and application that I can't know based on your description. I and others can assist you with further questions, though, if you decide to take that path :)

  • Related