Skip to content Skip to sidebar Skip to footer

Change Status Code Rails

I am in a really bad situation. I am using Volley on an Android application with Ruby on Rails JSON API. Problem is there is a bug with Volley making it unable to correctly identif

Solution 1:

Since devise is using warden you can create a custom failureapp and set the http status which you want.

In lib/custom_failure.rb

class CustomFailure < Devise::FailureApp
  def respond
    self.status = 403 
    self.content_type = 'json'
    self.response_body = { error: "Invalid Email or password."}.to_json
  end 
end

In config/initializers/devise.rb

config.warden do |manager|
  manager.failure_app = CustomFailure
end 

In config/application.rb

config.autoload_paths << Rails.root.join('lib')

Solution 2:

401 status code might come with a blank response data and if you check this volley code line 63-75

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

if jsonString is blank it still tries to create a JSONObject from it new JSONObject(jsonString) which throws a JSONException

You may download volley source code, import it as module in your android studio project, add it dependency and make this correction:

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
//          Fix for an error on blank success response
//          return Response.success(new JSONObject(jsonString),
//                    HttpHeaderParser.parseCacheHeaders(response));
            if (!jsonString.trim().contentEquals("")) {
                return Response.success(new JSONObject(jsonString),
                        HttpHeaderParser.parseCacheHeaders(response));
            }
            else {
                return Response.success(new JSONObject(),
                        HttpHeaderParser.parseCacheHeaders(response));
            }
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }
}

To add Volley to your project - clone the Volley repository and set it as a library project

  1. Git clone the repository by typing the following at the command line:

    git clone https://android.googlesource.com/platform/frameworks/volley

  2. Import the downloaded source into your app project as an Android library module as described in Create an Android Library.

You may also try Prase 401 volley error message if you don't want a fix inside the imported library:


Solution 3:

I found a solution to my problem from the Ruby on Rails backend side that is generalized for the whole application which is required as a lot of controllers would also give 401 and not only devise.

I have used Rack middleware by doing the following:

app/middleware/unauthorized_to_forbidden.rb

class   UnauthorizedToForbidden
    def initialize(app)
        @app = app 
    end

    def call(env)
        status, headers, response = @app.call(env)
        if(status == 401)
            status = 403
        end
        [status, headers, response]
    end
end

config/application.rb

class Application < Rails::Application
    config.middleware.use "UnauthorizedToForbidden"
end

Now UnauthorizedToForbidden is at the bottom of the Rack stack and gets executed at the very end before the response is actually sent to the user. It basically changes the status code if it's 401 to 403.


Post a Comment for "Change Status Code Rails"