Home > database >  Debug PG::InFailedSqlTransaction
Debug PG::InFailedSqlTransaction

Time:09-17

Some background

PG::InFailedSqlTransaction appears when some PG exception is rescued and prevents the transaction from rollback. Simple example:

ActiveRecord::Base.transaction do
  ActiveRecord::Base.connection.execute('SELECT nothing FROM nowhere') rescue nil
  binding.pry # <- let's assume we're here
  User.count # raises PG::InFailedSqlTransaction
end

The first line inside the transaction silently breaks the transaction and proceeds, any SQL statements after the first line will raise PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block.

The question

Assuming we're on the binding.pry breakpoint above, are there any ways to debug it and get the initial exception or any other data?
Not quite sure how it is implemented under the hood, but it seems quite possible for PG to cache some metadata about errors.

EDIT: the code above is just an example to demonstrate the general issue, the question is how to get the error in the situation when we cannot easily find the place that rescues the exception

CodePudding user response:

Per @engineersmnky comment, it is possible to get the last error message from the PG::Connection instance with #error_message method, the instance can be obtained from the ActiveRecord connection: ActiveRecord::Base.connection.raw_connection.error_message.

If we run the above command from the pry breakpoint in the example from the question, it will return the following message:

ERROR:  relation "nowhere" does not exist
LINE 1: SELECT nothing FROM nowhere
                            ^
  • Related