cassianoleal
cassianoleal

Reputation: 2566

How to properly check the HTTP response code in Ruby

I am writing a gem that will serve as a REST API client for the service my company provides.

For that, I have a Channel class that will serve as a means of interacting with the /channels path of the API. It uses HTTParty for the actual HTTP calls. This class has a method called create, that POSTs a Channel instance with the required attributes.

This is what the method looks like:

def create
  body = { external_id: external_id,
           name:        name,
           description: description }
  action = post "/", body
  case action.response.class
  when Net::HTTPAccepted      then return action
  when Net::HTTPNotAcceptable then raise HTTPNotAcceptable
  else raise "Server responded with " + Net::HTTPResponse::CODE_TO_OBJ[action.response.code].to_s
  end
end

The post method is an abstraction that transforms the body hash into JSON and attaches authentication and other attributes to the actual HTTParty call.

This does not work. Even when the response is a 202, this case statement always falls on the else condition. I have attached a pry session after the post call to verify that the response was correct:

    38: def create
    39:   body = { external_id: external_id,
    40:            name:        name,
    41:            description: description }
    42:   action = post "/", body
 => 43:   case action.response.class
    44:   when Net::HTTPAccepted      then return action
    45:   when Net::HTTPNotAcceptable then raise HTTPNotAcceptable
    46:   else raise "Server responded with " + Net::HTTPResponse::CODE_TO_OBJ[action.response.code].to_s
    47:   end
    48: end

[1] (pry) #<ZynkApi::Channel>: 0> action.response.class
=> Net::HTTPAccepted

But it still falls on else:

[1] (pry) #<ZynkApi::Channel>: 0> action.response.class
=> Net::HTTPAccepted
[2] (pry) #<ZynkApi::Channel>: 0> n

From: /Users/cassiano/projects/Zynk/src/zynk_api/lib/zynk_api/channel.rb @ line 38 ZynkApi::Channel#create:

    38: def create
    39:   body = { external_id: external_id,
    40:            name:        name,
    41:            description: description }
    42:   action = post "/", body
    43:   case action.response.class
    44:   when Net::HTTPAccepted      then return action
    45:   when Net::HTTPNotAcceptable then raise HTTPNotAcceptable
 => 46:   else raise "Server responded with " + Net::HTTPResponse::CODE_TO_OBJ[action.response.code].to_s
    47:   end
    48: end

Upvotes: 1

Views: 1333

Answers (1)

taro
taro

Reputation: 5832

Think about case statement like it uses === method:

if Net::HTTPAccepted === action.response.class
  puts 'accepted'
elsif Net::HTTPNotAcceptable === action.response.class
  puts 'not acceptable'
else
  puts 'unknown status'
end

But, as you know - class of most classes is a Class, so you should rewrite your case like this (without calling class method on response):

case action.response
  when Net::HTTPAccepted
    return action
  when Net::HTTPNotAcceptable
    raise HTTPNotAcceptable
  else
    raise "Server responded with " + Net::HTTPResponse::CODE_TO_OBJ[action.response.code].to_s
end

Upvotes: 2

Related Questions