Error in an after hook, PG::InFailedSqlTransaction from Rspec - ruby-on-rails

I was trying to run rspec from a model spec file, but I got this error: "An error occurred in an after hook"
"An error occurred in to after hook PG :: InFailedSqlTransaction:
ERROR: current transaction is aborted, commands ignored until end of
transaction. occurred at C :/ Ruby193/lib/.../postgresql_adapter: 294 "
I googled this issue, and I found a suggestion to downgrade my 'database_cleaner' to '1.0.1'. I did, but it doesn't work.
Does anyone have any idea how to solve this? Thanks in advance!

This can happen if you execute a bad SQL statement in the scope of a transaction, you rescue the exception from that statement, and then try and execute another SQL statement in the same transaction.
Once one statement in a transaction fails no more statements can be executed in that transaction.
Here's an example:
ActiveRecord::Base.transaction do
begin
ActiveRecord::Base.connection.execute "A bad query"
rescue => ex
puts ex.message
end
puts User.count
end
User.count raises PG::InFailedSqlTransaction because the previous SQL statement raised ActiveRecord::StatementInvalid and that was swallowed by the rescue.
So I would look for code that rescues in the scope of a transaction and then tries to run additional SQL statements.

Related

How to rollback failed transaction in rails console with pry

When trying out new active_record queries in the rails console with pry loaded, if a query causes an exception, I often have to stop the console and start it again, otherwise all queries cause an exception. I did have some code which appeared to fix this:
# .pryc
Pry.config.exception_handler = proc do |output, exception, _pry_|
output.puts "#{exception.class}: #{exception.message}"
output.puts exception.backtrace.first
if exception.instance_of?(ActiveRecord::StatementInvalid) && exception.original_exception.is_a?(PG::Error)
output.puts 'Rolling back transaction and starting a new one!'
connection = ActiveRecord::Base.connection
connection.rollback_db_transaction
connection.begin_db_transaction
end
end
but it appears to have stopped working in rails 5. The problem appears to be that exception.original_exception now raises this error
<NoMethodError: undefined method `original_exception' for #<ActiveRecord::StatementInvalid:0x00007fd2ceb4ba10>>
How do I fix this?

Rails App with Sinatra engine - How to avoid rails errors?

Problem: When running specs the output is very confusing, instead of saying where the error lies it just throws misleading errors
This is inside the rails lib folder, and it's mounted on the routes.rb
# lib/engines/users/app.rb
module Engines
module Users
class App < Sinatra::Base
get '/api/v1/users/me' do
raise 'runtime error here'
end
get '/api/v1/another-route' do
# something here
status 200
end
end
end
end
The spec file looks something like this:
it 'returns a 200' do
get '/api/v1/users/me', auth_attributes
expect(last_response.body).to eq 'something' # added to clarify my point, it's not the response status that I care of.
expect(last_response.status).to be 200
end
error:
Failure/Error: expect(last_response.status).to be 200
expected #<Fixnum:401> => 200
got #<Fixnum:1001> => 500
Compared using equal?, which compares object identity,
but expected and actual are not the same object. Use
`expect(actual).to eq(expected)` if you don't care about
object identity in this example.
expected error:
RuntimeError:
runtime error here
Another route also fails:
it 'something' do
get '/api/v1/another-route', auth_attributes
expect(last_response.status).to be 401
json = JSON.parse(last_response.body).with_indifferent_access
expect(json[:message]).to eql "You have been revoked access."
end
error: Prints a massive html output which I believe is the rails backtrace html output
expected error: none as this endpoint doesn't raise an error
My question is if there's a way to:
Stop rails from dealing with this, so it gives the actual output
Avoid the entire engine to fail because one route raise exception
I believe that by solving the first point, the second one gets fixed too.
Thank you for your time
In order to solve my problem I've discovered that on the spec_helper the ENV['RACK_ENV'] was not being set, setting it to test resolves the problem and throws the exception I need in order to debug my code.
This happens because https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1832
set :show_exceptions, Proc.new { development? }
development? returned true when in fact should be false (needed the RACK_ENV set to test)
Now I get the correct output.

Ruby rescue doesn't catch a StandardError

I'm writing tests for a Ruby Rails application, and I have a block of code that is supposed to catch an error thrown by my Redis server if Ruby cannot connect to it. Currently, the code looks like this:
begin
config.before(:all) { Resque.redis.select 1 }
config.after(:all) { Resque.redis.keys("queue:*").each { |key| Resque.redis.del key } }
rescue Exception
puts "RESCUED REDIS ERROR"
end
According to the stack trace when I try to run the tests, the second line of that code snippet -- config.before(:all) {...} -- throws a Redis::CannotConnectError. After a lot of "e.class.superclass.superclass..." commands, I determined that this error inherited from StandardError.
After that I got stuck. I tried catching the error with "rescue Redis::CannotConnectError", then "rescue", and finally "rescue Exception", but the error is still thrown. However, I tried the same things in the Ruby command prompt, and the exception was caught every time
Could anyone help me work out what's happening here? Thanks!
The problem is that the blocks passed to before and after are not being executed at the time they're defined; instead, they're being stored and then called later by Rspec before and after each spec file runs.
You'll probably want to move the begin/rescue within the blocks instead:
config.before(:all) do
begin
Resque.redis.select 1
rescue Exception
puts "RESCUED REDIS ERROR"
end
end
# same for config.after(:all)

Begin Rescue not catching error

I'm using some ruby code wrapped in a begin - rescue block but somehow it manages to still crash.
the block of code looks like this:
# Retrieve messages from server
def get_messages
#connection.select('INBOX')
#connection.uid_search(['ALL']).each do |uid|
msg = #connection.uid_fetch(uid,'RFC822').first.attr['RFC822']
begin
process_message(msg)
add_to_processed_folder(uid) if #processed_folder
rescue
handle_bogus_message(msg)
end
# Mark message as deleted
#connection.uid_store(uid, "+FLAGS", [:Seen, :Deleted])
end
end
Given this code i would assume that if process_message or add_to_processed_folder could not execute then rescue would kick in and call handle_bogus_message. That being said I'm running this code in a production environment and sometimes when i "get" an email message (this is run from a rake task) it dies with a SyntaxError.
For a look at the error message check out http://pastie.org/1028479 and not that process_message that it is referring to is the same process_message above. Is there any reason why begin - rescue won't catch this exception?
rescue without a parameter just rescues exceptions that inherit from StandardError. To rescue a SyntaxError use rescue SyntaxError.
To rescue all exceptions you would use rescue Exception, but note that that's a bad idea (which is why it's not the default behavior of rescue) as explained here and here. Especially this part:
Rescuing Interrupt prevents the user from using CTRLC to exit the program.
Rescuing SignalException prevents the program from responding correctly to signals. It will be unkillable except by kill -9.
rescue without any parameter accepts exceptions raised by StandardError class. Your error type is SyntaxError which is inherited from a different class called ScriptError. All these error classes are subclasses of Exception class. So as sepp2k suggested use rescue Exception to catch all kinds of exceptions.

display error message thrown by ms sql in ruby on rails

i've been looking for a solution for weeks now. yet still failed..i have stored procedure that was called using in ruby on rails..in that stored proc i have validations and thrown using raiserror.
ex. raiserror("StartDate must be less than EndDate")
in my ruby on rails controller
def save
begin
M.find_by_sql "EXEC spTestProc '3/15/2010', '3/1/2010'"
rescue Exception => e
render :js => alert(e.message);
end
but instead i get the error message "StartDate must be less than EndDate", I got this error message "DBI::DatabaseError: 37000 (50000) [Microsoft][ODBC SQL Server Driver][SQL Server]StartDate must be less than EndDate..: Exec spTestProc '3/15/2010', '3/1/2010'"
I need to display the error message thrown by my stored proc, but i got some additional message that I dont like to display like "DBI::DatabaseError...etc." how can I do this?
thanks.
Use regular expression to remove the unwanted text.
e.message.gsub(/(^.*SQL Server\])|(: Exec spTestProc.*$)/i, '')
# this will return StartDate must be less than EndDate..

Resources