2012-01-21 30 views
5

Tôi đang sử dụng find_by_sql để kết nối với cơ sở dữ liệu Postgres và thực thi chức năng cơ sở dữ liệu. Hàm cơ sở dữ liệu thực hiện một số câu lệnh SQL và tăng các ngoại lệ theo yêu cầu.Làm thế nào để bạn truy cập thông tin lỗi cơ sở dữ liệu khi sử dụng Rails và Postgres

Làm cách nào để bẫy mã lỗi và thông báo lỗi được tăng lên bởi hàm Postgres trong Rails?

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 

Tôi bắt đầu bằng cách tìm thông tin này trong đối tượng kết nối - không may mắn như vậy.

Bất kỳ trợ giúp nào được đánh giá cao.

Trả lời

0

Bạn có thể sử dụng các lỗi hàng loạt các mô hình của bạn, giống như những người khác cơ sở dữ liệu:

errmsg = YourModel.errors [0] .full_messages

+1

Cảm ơn bạn đã trả lời nhưng tôi e rằng điều này không thực sự hữu ích. –

+0

Sự hiểu biết của tôi là mảng lỗi được sử dụng để trình bày lỗi trở lại cho người dùng do xác thực mô hình. Điều này khác. Tôi đang tìm kiếm quyền truy cập vào SQLCode/SQLState được trả về bởi Postgres như là kết quả của một cuộc gọi find_by_sql. Điều này xảy ra trước khi bất kỳ thứ gì được thêm vào mảng lỗi. Trong thực tế, điểm của điều này là tôi đang tìm cách kiểm soát chính xác những gì được thêm vào mảng lỗi như là kết quả của cuộc gọi hàm SQL. –

+0

Tôi không thể thấy bất kỳ tài liệu nào ở bất cứ đâu về cách truy cập rõ ràng vào mã lỗi SQL. Có vẻ như tùy chọn duy nhất là thực hiện thao tác chuỗi để trích xuất nó từ thông báo lỗi. Rất không đạt yêu cầu. Tôi không thể tin rằng việc xử lý cơ sở dữ liệu là rất không linh hoạt nên có PHẢI là một giải pháp. –

3

kỷ lục Hiện nay hoạt động thay thế các lỗi ban đầu với một nội bộ một cái mà không truyền qua bản gốc với lỗi mới. Tôi không thể hiểu tại sao bất kỳ ai muốn điều này.

Vì vậy, giải pháp duy nhất bây giờ là bản vá khỉ;)

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 

Bây giờ bạn có thể nhận được 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 

Điều này làm việc với phiên bản pg 0.11 và Rails 3.0.9. Có lẽ sẽ làm việc với các phiên bản sau này.

+0

Nếu bạn không thích khỉ vá đi và bỏ phiếu yêu cầu kéo này. https://github.com/rails/rails/pull/5641 – Darwin

0

Tôi để cái này đi một lúc, (9 tháng!) Nhưng lại nhặt nó lên do một động lực mới.

tôi đã sử dụng bản vá khỉ được đề xuất bởi Darwin (xin lỗi rằng yêu cầu kéo didnt có được phiếu bầu) và đã sau đó phát hiện ra rằng mã tôi cần (có sự tham khảo http://deveiate.org/code/pg/PG/Result.html) như sau:

rescue ActiveRecord::WrappedDatabaseException => e 

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

Just xem .cause.

begin 
    # whatever. 
rescue => err 
    p err.cause 
end 
Các vấn đề liên quan