使用Rails和Postgres时如何访问数据库错误信息

时间:2012-01-21 10:13:21

标签: ruby-on-rails postgresql model error-handling

我使用find_by_sql连接到Postgres数据库并执行数据库功能。数据库函数执行许多SQL语句并根据需要引发异常。

如何捕获Rails中Postgres函数引发的错误代码和错误消息?

def self.validate_email(systemuserid, emailaddress)
  begin
    result = (self.find_by_sql(["SELECT fn_systemuser_validate_email(?, ?) AS returncode", 
                                systemuserid, emailaddress])).first
  rescue => err
    # I want to get access to the error code and error message here and act accordingly
    # errno = ??
    # errmsg = ??
    if errno == 10000
    end
  end
  return result[:returncode]
end

我开始试图在连接对象中找到这些信息 - 没有这样的运气。

任何帮助都非常感激。

4 个答案:

答案 0 :(得分:3)

当前活动记录使用内部错误替换原始错误,而不使用新错误传递原始错误。我不明白为什么会有人想要这个。

所以现在唯一的解决办法就是修补补丁;)

module ActiveRecord
  module ConnectionAdapters
    class AbstractAdapter
      def translate_exception(e, message)
        ActiveRecord::WrappedDatabaseException.new(message,e)
      end

      # Replaces
      # def translate_exception(e, message)
      #   # override in derived class
      #   ActiveRecord::StatementInvalid.new(message)
      # end
    end
  end
end

现在你可以获得original_exception。

def self.validate_email(systemuserid, emailaddress)
  begin 
    result = (self.find_by_sql(["SELECT fn_systemuser_validate_email(?, ?) AS returncode", systemuserid, emailaddress])).first
  rescue ActiveRecord::WrappedDatabaseException => e

    pgerror = e.original_exception

    # Exact api depends on PG version, check the docs for your version.
    puts "Doing my stuff: #{pgerror.result.result_error_message}"

  end
end

这适用于pg版本0.11和Rails 3.0.9。可能适用于更高版本。

答案 1 :(得分:0)

您可以像其他数据库一样使用模型的errors数组:

  

errmsg = YourModel.errors [0] .full_messages

答案 2 :(得分:0)

我让这一个人走了一段时间,(9个月!)但是由于新的动力再次把它拿起来。

我使用了达尔文建议的猴子补丁(很抱歉拉取请求没有得到投票)然后发现我需要的代码(参考http://deveiate.org/code/pg/PG/Result.html)如下:

rescue ActiveRecord::WrappedDatabaseException => e

  pgerror = e.original_exception
  sqlstate = pgerror.result.error_field(PG::Result::PG_DIAG_SQLSTATE )
end

答案 3 :(得分:0)

请看.cause

begin
  # whatever.
rescue => err
  p err.cause
end