AWS lambda API ruby responding differently on postman - ruby-on-rails

I am trying to execute some code using AWS lambda using ruby. The same code works well when using configured test event at the lambda function in AWS account, but when I send the same request using postman, it responds with 502 Bad Gateway response code.
When I watch cloudwatch logs, it gives an error message that is not possible on the code that is run.
require "payment_notification_response.rb"
Dir["payment_gateway/*.rb"].each {|file| require file }
class PaymentNotificationRequest
attr_accessor :headers, :body, :query_params, :http_method, :payment_gateway
PAYMENT_GATEWAYS = [::PaymentGateway]
def initialize(event)
self.headers = event["headers"] rescue {}
self.body = JSON.parse(event['body'].to_json, symbolize_names: true) rescue {}
self.query_params = event['queryStringParameters'] rescue {}
self.http_method = event["requestContext"]["http"]["method"] rescue {}
self.payment_gateway = self.find_payment_gateway_by_request
end
def find_payment_gateway_by_request
PAYMENT_GATEWAYS.each do |pg|
return pg if pg.new(self).is_the_requester?
end
end
def process
return self.payment_gateway.new(self).process
end
end
Below error is triggered at cloudwatch
{
"errorMessage": "undefined method `new' for [PaymentGateway]:Array",
"errorType": "Function<NoMethodError>",
"stackTrace": [
"/var/task/payment_notification_request.rb:23:in `process'",
"/var/task/lambda_function.rb:7:in `lambda_handler'"
]
}
How is this possible? Can anyone please help?

Related

How to catch a Rack RangeError in Rails 6

I have a Rails 6 app to which users can upload CSV files. Rails/Rack imposes a limit in the number of params that can be included in a request, and I've set this to a size larger than likely submissions to my app. However, I would like to return a friendly response if a too-large file is uploaded.
It looks like I need to add some custom middleware, to catch and rescue the error, but I can't get the code to work - the basic error is still raised without my rescue block being called.
The error from the server is:
Rack app error handling request { POST /[PATH_TO]/datasets }
#<RangeError: exceeded available parameter key space>
The code in my app/middleware/catch_errors.rb file is basically taken from a previous SO answer, where someone was catching ActionDispatch::ParamsParser::ParseError in JSON, but with my own code in the rescue block (which I realise may not work properly in this context, but that's not the issue right now):
class CatchErrors
def initialize(_app)
#app = _app
end
def call(_env)
begin
#app.call(_env)
rescue RangeError => _error
_error_output = "There were too many fields in the data you submitted: #{_error}"
if env['HTTP_ACCEPT'] =~ /application\/html/
Rails.logger.error("Caught RangeError: #{_error}")
flash[:error_title] = 'Too many fields in your data'
flash[:error_detail1] = _error_output
render 'static_pages/error', status: :bad_request
elsif env['HTTP_ACCEPT'] =~ /application\/json/
return [
:bad_request, { "Content-Type" => "application/json" },
[ { status: :bad_request, error: _error_output }.to_json ]
]
else
raise _error
end
end
end
end
I'm loading it in config.application.rb like this:
require_relative '../app/middleware/catch_errors'
...
config.middleware.use CatchErrors
I'm resetting the size limit for testing in app/initializers/rack.rb like this:
if Rack::Utils.respond_to?("key_space_limit=")
Rack::Utils.key_space_limit = 1
end
Any help gratefully received!
First, execute command to see all middlewares:
bin/rails middleware
config.middleware.use place your middleware at the bottom of the middleware stack. Because of that it can not catch error. Try to place it at the top:
config.middleware.insert_before 0, CatchErrors
Another point to mention, may be you will need to config.middleware.move_after or even config.middleware.delete some middleware. For instance, while tinkering I needed to place:
config.middleware.move_after CatchErrors, Rack::MiniProfiler

app signal gem send error to app signal without a crash request

I am using appsignal gem to track if there is an error processing in my app.
This case i do call external API using faraday.
def truck_information(req_params)
response = #conn.post('truck/info') do |req|
req.headers['Content-Type'] = 'application/json'
req.body = req_params
end
return JSON.parse(response.body) if response_successful?(response)
response_error(response)
end
def response_successful?(response)
response.status == 200
end
def response_error(response)
err = NctError, "Code: #{response.status}, response: #{response.body}"
Appsignal.set_error(err)
raise NctError, I18n.t('error_messages.ppob.server_error')
end
my truck_information is used to call external api. and if success i will parse it to json. but if error i will call response_error method parser to create custom class error (NctError) and i want to send to appsignal to show the error without breaking the application process.
But when i was tested it, it doesn't send to appsignal. How to do send error to appsignal, even if it doesn't crash a request? because i need to track the error.
Thank you
You could try Appsignal.send_error
Appsignal.send_error(err)
If above doesn't work either, then set_error and send_error may only work with Exception:
def response_error(response)
raise NctError, I18n.t('error_messages.ppob.server_error')
rescue => e
Appsignal.send_error(e) do |transaction|
transaction.params = { code: response.status, response: response.body }
end
end

CORS issue happening in tubesock

I have a Sinatra application which runs fine.Now to implement websockets I am using tubesock gem and have added following code
class Server
def call(env)
if env["HTTP_UPGRADE"] == 'websocket'
tubesock = Tubesock.hijack(env)
tubesock.onmessage do |message|
puts "Got #{message}"
end
tubesock.listen
[ -1, {}, [] ]
else
[404, {'Content-Type' => 'text/plain'}, ['Not Found']]
end
end
end
Now it is giving CORS error(Cross origin error).Previously it was working fine.Any suggestions?
Thanks
I was able to use rack/cors and resolve the issue

Shopify :: ActiveResource::ForbiddenAccess: Failed. Response code = 403. Response message = Forbidden

I have sent the app(not listed yet) for review. The reviewer is getting the mentioned error on index action of HomeController which triggers when user clicks on install button. I verified the app with many development stores in different partners account. I was able to install the app sucessfully for all the stores I tested.
Here is simplified version of the code
controllers/shopify/home_controller.rb
module Shopify
class HomeController < ShopifyApp::AuthenticatedController
def index
MyCustomServie.new(shopify_detail).call
end
private
def current_shopify_store
#current_shop ||= begin
Shopify::Base.with_rate_limit_protection do
ShopifyAPI::Shop.current
end
end
end
def shopify_detail
#shopify_detail ||= ShopifyDetail.find_by(shopify_domain: current_shopify_store.try(:myshopify_domain))
end
end
end
config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :shopify,
ShopifyApp.configuration.api_key,
ShopifyApp.configuration.secret,
scope: ShopifyApp.configuration.scope,
callback_path: "#{Settings.shopify.mounted_at}/auth/shopify/callback"
provider :google_oauth2,
Settings.google.client_id,
Settings.google.client_secret,
{ access_type: "offline", approval_prompt: "" }
end
conffig/initializers/shopify_app.rb
ShopifyApp.configure do |config|
config.application_name = 'Shopify - Feed Champion'
config.api_key = Settings.shopify.api_key
config.secret = Settings.shopify.api_secret
config.scope = Settings.shopify.scope
config.embedded_app = true
config.after_authenticate_job = { job: ShopifyAfterAuthenticateJob, inline: true }
config.webhooks = [ Shopify::AppUninstalledWebhook::PARAMS ]
end
The error comes from the below line
ShopifyAPI::Shop.current
Here is the error log. Can anybody give pointers where could be the problem?
Being a newbie to Shopify, I missed adding required scopes for using available Shopify APIs, and was getting the same ForbiddenAccess error.
In shopify_app.rb I added missing scopes. Example for fetching all products and customers of a Shopify store:
config.scope = "read_products, read_customers"
Here is the list of all available scopes.

How to use SOAP service with xml in Rails (EU VAT number check)

I'd like to add a method in my Rails application that checks the validity of a VAT number using the EU's VIES system: http://ec.europa.eu/taxation_customs/vies/technicalInformation.html
I'm already pretty new to programming in Rails and the instructions here use xml. So I have trouble figuring this out. How should I include the code mentioned on the mentioned website in my Rails application?
In other words, what should the validate_vat(country, vatnumber) method below look like and how to process the response received from the SOAP service?
def vatsubmission
#organization = Organization.find(params[:id])
#organization.update_attributes(vat_params)
#organization.validate_vat(#organization.country, #organization.vatnumber) if (#organization.vatnumber? && #organization.vatnumber?)
# Process response
if valid == false
#organization.update_attributes(valid_vat: false)
flash.now[:danger] = "False VAT number"
render ...
elsif valid == true
#organization.update_attributes(valid_vat: true)
flash.now[:success] = "VAT number validated"
render ...
else
flash.now[:danger] = "VAT number could not be validated"
render ...
end
end
def validate_vat(country, vatnumber)
??
end
Update: I've added gem 'savon', '2.11.1' to my gemfile. In my controller I have:
def update
#organization = Organization.find(params[:id])
if #organization.check_valid == true
#organization.update_attributes(validnr: true)
else
#organization.update_attributes(validnr: false)
end
end
And I have added the following model method:
require 'savon'
def check_valid
debugger
if ["DK", "CY", "etc"].include? self.country
client = Savon.client(wsdl: 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl')
resp = client.call :check_vat do
message country_code: self.country, vat_number: self.vatnr
end
data = resp.to_hash[:check_vat_response]
data[:valid]
end
end
Error: The line message country_code: self.country, vat_number: self.vatnr fails with the error message: wrong number of arguments (1 for 2). I checked with the debugger and self.country as well as self.varnr do have values. What am I doing wrong?
For working with SOAP from Ruby I used excelent Savon gem.
With Savon v2, working code looks like this:
require 'savon'
client = Savon.client(wsdl: 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl')
resp = client.call :check_vat do
message country_code: 'AT', vat_number: '123'
end
data = resp.to_hash[:check_vat_response]
data[:valid] #=> false :)
Note Savon v3 is still in preparation.
I've just started using the ValVat gem for this and it workd beautifully so far!

Resources