While I'm parsing alliance feed in a Sinatra/Ruby app I get the error:
/opt/rh/ruby200/root/usr/share/ruby/net/http/response.rb:368: [BUG]
Segmentation fault ruby 2.0.0p645 (2015-04-13) [x86_64-linux]
I'm wondering if this is a bug with Ruby or something wrong with the code, and if so, what could I do to fix it?
Link to the error
This is the code for the parsing alliance feed:
feeds.each { |name, hash|
puts "=== PARSING #{name.upcase} FEED ==="
start = Time.now
open(hash[:url]) { |feed|
send(hash[:action], feed)
}
duration = Time.now - start
puts "Feed syndication completed in #{duration.to_s} seconds."
puts
}
# Close DB connection
puts "Disconnecting"
#db.disconnect
end
def parseAllianceData(xml)
start = Time.now
allianceData = XMLObject.new xml
duration = Time.now - start
puts "XML parsed in #{duration.to_s} seconds."
puts "Alliances found: #{allianceData.alliances.count}"
#db[:feeds].insert(
:generated_at => allianceData.server.datagenerationdatetime,
:type => "Alliance",
:is_current => true)
start = Time.now
allianceData.alliances.each { |alliance|
capital_last_moved_at = (alliance.alliancecapitallastmoved rescue nil)
taxrate_last_changed_at = (alliance.alliancetaxratelastchanged rescue nil)
#db[:alliance].insert(
:id => alliance.alliance[:id],
:ticker => alliance.allianceticker,
:name => alliance.alliance,
:founded_at => alliance.foundeddatetime,
:founded_by_player_id => alliance.foundedbyplayerid[:id],
:capital_town_id => alliance.alliancecapitaltownid[:id],
:member_count => alliance.membercount,
:total_population => (alliance.totalpopulation rescue 0),
:tax_rate => (alliance.alliancetaxrate.to_i) / 100.0,
:tax_rate_last_changed_at => taxrate_last_changed_at,
:capital_town_last_moved_at => capital_last_moved_at)
alliance.roles.each { |role|
#db[:alliance_roles].insert(
:id => role.role[:id],
:name => role.role,
:alliance_id => alliance.alliance[:id],
:hierarchy_id => role.heirarchy[:id])
}
}
duration = Time.now - start
puts "Database populated in #{duration.to_s} seconds."
I spot one dangerous line of code in your sample:
send(hash[:action], feed)
It takes some string from external source (hash[:action]) and turns it into a method call. It is very dangerous, because you never know what string you will get. There could be a string there that cannot be made into a method call so Ruby crashes.
I would suggest checking for all supported actions and calling methods explicitly. You can do it with a case statement, for example.
action = hash[:action]
case action
when 'action1'
call_method1
when 'action2'
call_method2
else
puts "unsupported action: #{action}"
end
Related
I am new to WSDL.
Code (I have added in the view directly - for test): (Page: http://localhost:3000/ccapis )
require 'savon'
client = Savon::Client.new(wsdl: "http://localhost:3000/ccapis/wsdl")
result = client.call(:fetch_prizes, message: { :gl_id => "123456789" })
result.to_hash
And in the controller:
soap_action "fetch_prizes",
:args => { :gl_id => :string },
:return => [:array]
def fetch_prizes
glnumber = params[:gl_id ]
prize = Prize.where(:gl_id => glnumber)
prize_to_show = []
a_hash = {}
prize.each do |p|
a_hash = { :prize => p.prize.to_s, :score => p.score.to_s, :date => p.round_date.to_s }
prize_to_show.push a_hash
a_hash = nil
end
render :soap => prize_to_show
end
When I try and run this in the Console all are good and I can see the result.to_hash but when I go to http://0.0.0.0:3000/ccapis I get the error that I mentioned above.
Explanation of what I am trying to achieve:
I need to supply a WSDL for a client which fetches all the prizes based on a score.
If My approach is wrong please direct me to a document so I can have a read and get a better understanding. Thanks again.
I want to use 'tinymce_spellcheck' to use the spellcheck button in my tinymce editor.
I wrote in my controller:
def spellcheck
data = ActiveSupport::JSON.decode(request.raw_post)
args = data['params'].to_a.first
spellcheck = TinymceSpellcheck.new({}, :raspell)
result = spellcheck.send(data['method'].underscore,*args) #****---- THIS LINE****
render :json => { :id => data['id'], :result => result, :error => nil }.to_json
end
I get the following error message:
ArgumentError (wrong number of arguments (1 for 2)):
app/controllers/members_controller.rb:127:in `spellcheck'
Would you be so kind to tell me how to solve this problem? I am providing two arguments and, yet, I get the same error message again and again.
Well, the problem is probably that args is empty or nil, so when you call the splat on it, it turns into zero arguments. Thus, your only argument is the 'method', and you get an ArgumentError.
def spellcheck
`data = ActiveSupport::JSON.decode(request.raw_post)
args = data['params'].to_a.first
spellcheck = TinymceSpellcheck.new({}, :raspell)
result = spellcheck.send(data['method'].underscore,*args)
render :json => { :id => data['id'], :result => result, :error => nil }.to_json
end`
The line `args = data['params'].to_a.first` was changed to`args = data['params'].to_a`
controller code:
def create
if current_user.id != params[:friend_id]
#return = { :curr_user_id => current_user.id, :params_id => params[:friend_id], :debug => 1 }
else
#return = { :curr_user_id => current_user.id, :params_id => params[:friend_id], :debug => 2 }
end
render :json => ActiveSupport::JSON.encode( #return )
end
so current_user.id is 1 and params[:friend_id] is being passed via an ajax call and its value is also 1
the problem is that it always returns true when it should return false in this case... is there anything that has to do with the number 1 being parsed as string instead of integer?
params are always strings, use:
if current_user.id != Integer(params[:friend_id])
I don't recommend to_i, look why:
"abc".to_i # => 0 which is unexpected
Integer("abc") # => raises error, which is fine
I have a method in my model Post like this:
def self.post_template
posts = Post.all
result = []
posts.each do |post|
single_post = {}
single_post['comment_title'] = post.comment.title
single_post['comment_content'] = post.comment.content
result << single_post
end
# return the result
result
end
In one of my rake tasks, I call the function:
namespace :post do
task :comments => :environment do
comments = Post.post_template
puts comments
end
end
In the console, the return value isn't an Array; instead, it prints all the hashes separated by a newline:
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }
However, when I run this in my rails console, I get the expected behavior:
> rails c
> comments = Post.post_template
-- [{ 'comment_title' => 'stuff', 'comment_content' => 'content' },
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }]
Needless to say, I'm pretty confused and would love any sort of guidance! Thank you.
EDIT:
Seems rake tasks simply print out arrays like this, but when I set the result of my array into another hash, it does not seem to maintain the integrity of the array:
namespace :post do
task :comments => :environment do
comments = Post.post_template
data = {}
data['messages'] = comments
end
end
I'm using Mandrill (plugin for Mailchimp) to create these messages and it throws an error saying that what I'm passing in isn't an Array.
I think that's just how rake prints arrays. Try this:
task :array do
puts ["First", "Second"]
end
Now:
> rake array
First
Second
I am trying to parse XML using rexml Xpath, but facing error as const_missing: XPath in rhomobile application. can anyone give me the solution.
Below is the sample code:
file = File.new(file_name)
begin
require 'rexml/document'
xmldoc = REXML::Document.new(file)
names = XPath.match(xmldoc, "//MP_HOST_NAME" )
in your build.yml file:
extensions:
- rexml
if using blackberry, replace rexml with rhoxml
Assuming you've done this, replace your XPath with:
REXML::XPath.match(xmldoc, "//MP_HOST_NAME" )
Here is a sample controller I knocked to test xml parsing
I can use the get_names method in the view then to get an array of names
require 'rho/rhocontroller'
require 'rexml/document'
class WebServiceTestController < Rho::RhoController
def index
##get_result = ""
Rho::AsyncHttp.get(
:url => 'http://www.somesite.com/some_names.xml',
#:authorization => {:type => :basic, :username => 'user', :password => 'none'},
:callback => (url_for :action => :httpget_callback),
:authentication => {
:type => :basic,
:username => "xxxx",
:password => "xxxx"
},
:callback_param => "" )
render :action => :wait
end
def get_res
##get_result
end
def get_error
##error_params
end
def httpget_callback
if #params["status"] != "ok"
##error_params = #params
WebView.navigate( url_for(:action => :show_error) )
else
##get_result = #params["body"]
begin
# require "rexml/document"
##doc = REXML::Document.new(##get_result)
# puts "doc : #{doc}"
rescue Exception => e
# puts "Error: #{e}"
##get_result = "Error: #{e}"
end
WebView.navigate( url_for(:action => :show_result) )
end
end
def show_error
render :action => :error, :back => '/app'
end
def show_result
render :action => :index, :back => "/app"
end
def get_doc
##doc
end
def get_names
names = []
REXML::XPath.each( get_doc, "//name_or_whatever_you_are_looking_for") do |element|
names << element.text
end
names
end
end
ensure that rhoxml is set in the build.yml file rather than rexml this works fine and it's a little faster