Handling exceptions in Rails API request - ruby-on-rails

I have an API with an endpoint that makes a request to a third-party service. I am trying to pass the error from the module to my controller so I can return the error in my API response. This issue is that I cannot seem to access the error.
# controller
def download_pdf
doc = SignedDocument.find(params[:id])
begin
data = EsignGenie.downloadDocumentFromFolder(doc.folder_id, doc.document_number)
render json: {data: data}, status: :ok
rescue Exception => e
render json: e, status: :unprocessable_entity
end
end
#module
def self.downloadDocumentFromFolder(folder_id, document_number)
url = "https://www.esigngenie.com/esign/api/folders/document/download?folderId=#{folder_id}&docNumber=#{document_number}"
begin
response = RestClient::Request.execute(method: :get, url: url, raw_response: true, headers: {Authorization: "Bearer #{ENV['ESIGNGENIE_AUTH']}"} )
rescue => e
# the exception I'd like to pass to the controller
p "e.http_body", e.http_body
throw e
end
data = Base64.encode64(File.open(response.file).read)
end
What am I doing wrong here?

Related

Render is not giving the response in rails

In my application the render is not showing the response on browsers console.
my controller class is-
def create
ActionItem.transaction do
#action = #doc.action_items.new(action_item_params)
#action.minutes_section = #section if #section
# Were we passed a sort_order? If not, default to the highest sort
# order number for this action item's section. minutes-app may
# also pass us -1 to indicate we should compute the next value.
if !action_item_params.key?(:sort_order) or [-1, nil, ""].include?(action_item_params[:sort_order])
result = ActionItem.where(minutes_document_id: #doc.id, minutes_section_id: #section.id).maximum('sort_order')
if result.nil?
#action.sort_order = 0
else
#action.sort_order = result + 1
end
end
if #action.save!
#action.action_items_statuses.create!(status: 'incomplete', status_type: 'completion', contact_id: current_user.id)
#action.action_items_statuses.create!(status: 'unsent', status_type: 'notification', contact_id: current_user.id)
#action.action_items_statuses.reload
handle_assignees(#action, params[:data][:attributes][:assignees]) if !params[:data][:attributes][:assignees].blank?
handle_note(#action, params[:data][:attributes][:note])
render(json: #action, status: 201)
else
render(json: { error: #action.errors }, status: 500)
end
end
rescue ActiveRecord::ActiveRecordError => e
Rails.logger.error e.message
render(json: { error: e.message }, status: 500)
end
I am not getting the response on console-
Error

server responded with a status of 404 (Not Found)

I am trying to redo my react rails app with gresql so that I can deploy it with heroku. So far everything is working fine except the fetch POST request. I am getting a 404 (Not Found) error and binding.pry isn't coming up in my terminal so I can't see from the controller.
I think it might have something to do with how it is sending back json with render :json. Before I was using respond_to do |format| format.json {.
import fetch from 'isomorphic-fetch';
export function saveData(rec) {
debugger
return function(dispatch){
return fetch(`/api/v1/charts`, {
credentials: "include",
method: "POST",
headers: {
'Accept': "application/json",
'Content-Type': "application/json",
},
body: JSON.stringify(rec)
})
.then(res => {
return res.json()
}).then(data => {
debugger
dispatch({type: 'ADD_CHART', payload: data})
})
}
}
module Api::V1
class ChartsController < ApplicationController
def index
#charts = Chart.all
render json: #charts, include: ["people", "weights"]
end
def create
binding.pry
#chart = Chart.create(chart_params)
render json: #chart, include: ["people", "weights"]
end
def destroy
Chart.find(params[:id]).destroy
end
private
def chart_params
params.require(:chart).permit(:id, :date, people_attributes: [:name, weights_attributes: [:pounds, :currentDate] ])
end
end
end
module Api::V1
class PersonsController < ApplicationController
def index
#persons = Person.all
render json: #persons, include: "weights"
end
def create
binding.pry
#person = Person.create(person_params)
render json: #person, include: "weights"
end
private
def person_params
params.require(:person).permit(:id, :name, weights_attributes: [:pounds, :currentDate])
end
end
end
module Api::V1
class WeightsController < ApplicationController
def index
#weights = Weight.all
render json: #weights
end
def create
binding.pry
e = Weight.where(:person_id => params[:person_id], :currentDate => params[:currentDate])
if !e.empty?
e.first.pounds = params[:pounds]
e.first.save!
#weight = e
else
#weight = Weight.create(weight_params)
end
render json: #weight
end
private
def weight_params
params.require(:weight).permit(:id, :pounds, :currentDate, :person_id)
end
end
end
class ApplicationController < ActionController::API
end
If you've declared resource routes for your charts, you need to change this line:
return fetch(`/api/v1/charts`, {
to:
return fetch(/api/v1/chart, {
As is, charts is likely triggering a POST to your index action.
Changing my fetch to the full url and removing credentials: "include" worked
import fetch from 'isomorphic-fetch';
export function saveData(rec) {
debugger
return function(dispatch){
var url = 'http://localhost:3001/api/v1/charts';
return fetch(url, {
method: "POST",
headers: {
'Accept': "application/json",
'Content-Type': "application/json",
},
body: JSON.stringify(rec)
})
.then(res => {
return res.json()
}).then(data => {
debugger
dispatch({type: 'ADD_CHART', payload: data})
})
}
}

How to render a jsonapi-resources response in an custom controller action?

I have implemented my own object creation logic by overriding the create action in a JSONAPI::ResourceController controller.
After successful creation, I want to render the created object representation.
How to render this automatically generated JSON API response, using the jsonapi-resources gem?
Calling the super method does also trigger the default resource creation logic, so this does not work out for me.
class Api::V1::TransactionsController < JSONAPI::ResourceController
def create
#transaction = Transaction.create_from_api_request(request.headers, params)
# render automatic generated JSON API response (object representation)
end
end
You could do something like this:
class UsersController < JSONAPI::ResourceController
def create
user = create_user_from(request_params)
render json: serialize_user(user)
end
def serialize_user(user)
JSONAPI::ResourceSerializer
.new(UserResource)
.serialize_to_hash(UserResource.new(user, nil))
end
end
this way you will get a json response that is compliant with Jsonapi standards
render json: JSON.pretty_generate( JSON.parse #transaction )
def render_json
result =
begin
block_given? ? { success: true, data: yield } : { success: true }
rescue => e
json_error_response(e)
end
render json: result.to_json
end
def json_error_response(e)
Rails.logger.error(e.message)
response = { success: false, errors: e.message }
render json: response.to_json
end
render_json { values }

XMLHttpRequest cannot load http://localhost:3000/players/1. Response for preflight has invalid HTTP status code 404

I am building a react-native app with rails api. I have a players_controller with create, index, update actions. I can do all things(create, index, update) from postman. But when I tried form fetch request from react action. I could only index and create player model. On update I get this error in debugger console.
:3000/players/1:1 OPTIONS http://localhost:3000/players/1
XMLHttpRequest cannot load http://localhost:3000/players/1. Response
for preflight has invalid HTTP status code 404
in Rails my players_controller.rb
class PlayersController < ApplicationController
skip_before_action :verify_authenticity_token
respond_to :json
def index
#players = Player.find_by(player_id: params[:player_id])
player = Player.all
render json: #players
end
def create
player = Player.new(player_params)
if player.save
render json: player, status: 201
else
render json: { errors: player.errors }, status: 422
end
end
def update
player = Player.find(params[:id])
player.update(player_params)
if player.save
render json: player, status: 201
else
render json: { errors: player.errors }, status: 422
end
end
private
def player_params
params.require(:player).permit(:username, :profile_pic, :player_id)
end
end
In my react-native app I have action
export const profilePicUpdate = (player, profile) => (dispatch) => {
const obj = player;
obj.profile_pic = profile;
fetch(`http://localhost:3000/players/${player.id}`, {
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
obj
})
}).then(() => {
dispatch({
type: 'PROFILE_PIC_UPDATE',
payload: profile
});
NavigatorService.navigate('Profile');
}).catch((error) => {
console.log('Error', error);
});
};
It is need to see your roues.rb file, but also maybe you need to add
gem 'rack-cors'
and set up it
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
in config/initializers/cors.rb

wit.ai Ruby Gem, repeated calls, call doesn't end

I'm using a Ruby Gem for wit.ai, and have created an API in ROR that queries the wit.ai client.
But unexpectedly the method in the API keeps on calling the client method repeatedly, even after getting the response.
Because of which the API method never renders the JSON response.
How can I resolve this issue? Why is this happening?
It works perfectly fine if I do the same thing from Rails Console.
ApiController
module Api
module V0
class ApiController < ApplicationController
def response
q = params[:q]
response = Api::V0::ApiModel.handle_response q
render :json => response, :status => 200
end
end
end
end
ApiModel
module Api
module V0
class ApiModel
def self.handle_response q
response = ChatbotHelper.query q
if response['type'] == "msg"
message = response["msg"]
json = {"message" => message}
else
json = response
end
json
end
end
end
end
ChatbotHelper
module ChatbotHelper
def self.init
actions = {
send: -> (request, response) {
puts "REQUEST #{request} RESPONSE #{response}"
puts("#{response['text']}")
response
},
getData: -> (context){
},
}
#client = Wit.new(access_token: "XYZ", actions: actions)
end
def self.query q
begin
self.init
response = self.get_response q
rescue SocketError
response = {"message": "SocketError"}
end
response
end
def self.get_response q
puts "GET RESPONSE"
response = #client.converse("b", q, {})
response
end
end
Ahh! it was happening due to the name of the function in the API Controller, i.e. response.. Seems like its an inbuilt function for ROR..

Resources