Feature Requests: Browse | Submit New | Admin

[#27227] DBI::DBD API improvement - unified error handling in DBI

Date:
2009-10-03 03:19
Priority:
1
Submitted By:
Mike Pomraning (pilcrow)
Assigned To:
Nobody (None)
Category:
Interface Improvements (example)
State:
Open
Summary:
DBI::DBD API improvement - unified error handling in DBI

Detailed description
Summary:
The DBI::Handle layer should trap and translate DB layer errors, using a conversion function registered by the DBD layer
(by the dbd-driver).  See below for possible API.

Background:
Currently (dbi-0.4.3), each DBD is responsible for transforming its underlying DB layer exceptions into the appropriate
DBI::DatabaseError derivative, as the DBI layer passes on any exceptions.

DBDs typically must everywhere rescue the underlying SqlDriverError to re-raise its DBI analog, which means that some
error trapping is invariably omitted.  For example, no dbd-mysql-0.4.3 ``Mysql::Database#__native_func'' methods wrap
mysql-specific errors.  Further, many DBDs do not take full advantage of the DBI::DatabaseError class, setting only
a message but not setting the @err nor @state (SQLSTATE) members.

Possible API:

    # lib/dbd/mockesscueell/driver.rb
    #  -- trap and translate MockSQLError
    DBI::ErrUtil.register_error_conv(driver_name, MockSQLError) do |err, handle, method|
       # 'err' - the MockSQLError exception object
       # 'handle' - DBI::Handle derivative (e.g., StatementHandle) rescue'ing
       # 'method' - name of the method in which the DBI is rescue'ing err
       klass = case err.sqlstate
               when /^08/
                 DBI::ConnectionError
               ...
       return klass.new(err.message, err, err.sqlstate)
    end

    # lib/dbi/handles/statement.rb
    def finish
       @handle.finish
    rescue
       # will simply return $! unmodified if there's no conversion
       raise DBI::ErrUtil.convert_error(self.dbh.driver_name, $!)
    end

Other approaches:

One might also wrap or delegate the underlying DB handle, trapping and re-raising all errors there.  However, at that
low level there'd be many unneeded rescue's which could be aggregated, and the error handler wouldn't necessarily know
the high-level operation in whose service it was ultimately called.  (And this is somewhat slow in my testing!)

Add A Comment: Notepad

Please login


Followup

No Followups Have Been Posted

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item