Redirecting to a 500 page when an AJAX call fails in Ruby on Rails
Asked Answered
R

4

6

I'm working with an application built in Ruby on Rails with very poor error handling right now. If a controller method is executed via ajax, and that method results in a 500 (or 404 or any other response) the 500.html page is rendered and returned as the result to the AJAX request. Obviously the javascript doesn't know what to do with that HTML and the web page looks like it's just waiting for a response.

Is there an easy way in rails to render an error.rjs template anytime an error occurs during an AJAX call?

Rhnegative answered 6/3, 2009 at 19:24 Comment(0)
B
3

You can use respond_to inside a controller's rescue_action or rescue_action_in_public method. Consider the following controller:

class DefaultController < ApplicationController

  def index
    raise "FAIL"
  end

  def rescue_action(exception)
    respond_to do |format|
      format.html { render :text => "Rescued HTML" }
      format.js { render :action => "errors" }
    end
  end
end
Bridal answered 7/3, 2009 at 2:57 Comment(0)
R
3

I solved a similar problem with authorization. I created a simple authorization controller with this action:

  def unauthorizedxhr
    render :update do |page|
      page.replace_html("notice", :partial=>"unauthorizedxhr")
      page.show("notice")       
    end
  end

Here's the template:

<% if flash[:notice] -%>
    <div id="noticexhr"><%= flash[:notice] %></div>
<% end -%>

When the authorization failed in the controller, I'd redirect to the :controller=>"authorization", :action=>"unauthorizedxhr" after setting the flash[:notice] value. This allowed me to customize the message I sent to the user, and it handled the display of the message through the render :update code above.

You could adapt this to your problem by creating an errors controller, catching any raised errors in your other controllers, then simply redirecting to :controller=>"errors", :action=>"displayxhr" when the call fails. That way, you'll have standardized your error communication mechanism but allowed yourself the ability to customize error messages by each action.

You can still use cpm's idea above, but the error's display will be handled by separate and distinct controller logic. that should make it a little easier to maintain.

Hope that helps. -Chris

Retina answered 7/3, 2009 at 16:27 Comment(0)
R
1

This was my final solution:

def rescue_action_in_public(exception)
  response_code = response_code_for_rescue(exception)
  status = interpret_status(response_code)
  respond_to do |format|
    format.html { render_optional_error_file response_code}
    format.js { render :update, :status => status  do |page| page.redirect_to(:url => error_page_url(status)) end}
  end
end

This basically forwards to the correct static HTML page no matter if the request was via AJAX or normal GET/POST.

This is NOT used for normal error handling like validation etc. It's only used when something really bad happens - like an unhandled exception.

Rhnegative answered 20/3, 2009 at 20:47 Comment(0)
G
0

You can do like below :

in allpication.js

$(document).ready(function(){
    $(document).ajaxError( function(e, xhr, options){
    if("500" == xhr.status)
    {
       $(location).attr('href','/users/sign_in');
    }
  });
}) 

Its working for me.....

Gilberto answered 18/11, 2011 at 8:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.