0

I want to rescue every 403 response from S3 in my app. They're mostly in image tags, breaking the image in the view. How can I do that in ApplicationController when the image tags don't raise exceptions, they just have broken images in the view?

rescue_from ??? do |e|
  logger.debug "broken image: #{e}"
end

Some images are rendered in a helper like so:

def user_image(img_style)
 "<img src='#{asset.image(img_style)}' />"
end

Where asset.image(img_style) returns a (in this case forbidden) URL.

Others are just like:

<%= image_tag document.other_asset.image(:small) %>

There's no single parent controller (save ApplicationController) I guess.

There is, however, a single polymorphic class (ImageAttachment) that stores the image. Should I fetch it in the model beforehand and raise the error? Doesn't that involve making the request twice?

t56k
  • 6,769
  • 9
  • 52
  • 115
  • 1
    Can we see how you are loading the images, and what your controller looks like? – Garrett Motzner Jan 18 '19 at 00:03
  • There's nothing non-standard there. I'm also talking system-wide, not just under a particular controller. Some are rendered directly into image tags, which I'll show, and others just in the view with an `image_tag`. – t56k Jan 18 '19 at 00:14
  • Exactly what @GarrettMotzner said, we need some more context on how you're loading images. You probably need to check the HTTP response code from the S3 request. A HTTP status code of `403` wouldn't directly raise an error in your application – hummmingbear Jan 18 '19 at 00:14

1 Answers1

0

This solution is absolutely horrible and doubles the number of requests per image, but for completion's sake:

def found?(style = :small)
  return true if URI.open(image(style))
rescue OpenURI::HTTPError => exception
  logger.debug exception.message
  false
end

A better implementation obviously is in Javascript so resources don't have to be loaded twice, but since the question started with Ruby it'll end there, too.

t56k
  • 6,769
  • 9
  • 52
  • 115