Fixes #166 by handling exceptions when logging

This commit is contained in:
Sean Corfield 2021-06-12 13:47:22 -07:00
parent 164572969b
commit 6fe7d5b91c
4 changed files with 24 additions and 13 deletions

View file

@ -3,8 +3,8 @@
Only accretive/fixative changes will be made from now on. Only accretive/fixative changes will be made from now on.
* 1.2.next in progress * 1.2.next in progress
* _[Experimental! Will change in response to feedback!]_ Add `next.jdbc/with-logging` to create a wrapped connectable that will invoke logging functions with the SQL/parameters and optionally the result for each operation.
* Fix #167 by adding `:property-separator` to `next.jdbc.connection/dbtypes` and using it in `jdbc-url`. * Fix #167 by adding `:property-separator` to `next.jdbc.connection/dbtypes` and using it in `jdbc-url`.
* Address #166 by adding `next.jdbc/with-logging` to create a wrapped connectable that will invoke logging functions with the SQL/parameters and optionally the result or exception for each operation.
* Fix `:unit_count` references in **Getting Started** (were `:unit_cost`). * Fix `:unit_count` references in **Getting Started** (were `:unit_cost`).
* Update `test-runner`. * Update `test-runner`.

View file

@ -592,7 +592,9 @@ operations directly so they do not produce results). `my-result-logger` will be
three arguments: three arguments:
* The fully-qualified symbol identify the operation, * The fully-qualified symbol identify the operation,
* A "state" argument (the result of calling `my-sql-logger`), * A "state" argument (the result of calling `my-sql-logger`),
* The result set data structure. * The result set data structure, if the call succeeded, or the exception if it failed.
The return value of the result logger function is ignored.
The symbol will be one of: `next.jdbc/execute!` or `next.jdbc/execute-one!`. The friendly The symbol will be one of: `next.jdbc/execute!` or `next.jdbc/execute-one!`. The friendly
SQL functions invoke `execute!` or `execute-one!` under the hood, so that is how they will SQL functions invoke `execute!` or `execute-one!` under the hood, so that is how they will
@ -605,7 +607,8 @@ returns `nil`, that will be passed as the second argument to your second logging
The result set data structure could be arbitrarily large. It will generally be a vector The result set data structure could be arbitrarily large. It will generally be a vector
for calls to `execute!` or a hash map for calls to `execute-one!`, but its shape is determined for calls to `execute!` or a hash map for calls to `execute-one!`, but its shape is determined
by any `:builder-fn` options in effect. by any `:builder-fn` options in effect. You should check if `(instance? Throwable result)`
to see if the call failed and the logger has been called with the thrown exception.
For `plan` and `prepare` calls, only the first logging function is invoked (and the return For `plan` and `prepare` calls, only the first logging function is invoked (and the return
value is ignored). You can use the symbol passed in to determine this. value is ignored). You can use the symbol passed in to determine this.

View file

@ -390,10 +390,10 @@
The result logging function, if provided, will be called with the The result logging function, if provided, will be called with the
same symbol passed to the sql/params logging function, the `state` same symbol passed to the sql/params logging function, the `state`
returned by the sql/params logging function, and the result of the returned by the sql/params logging function, and either the result of
`execute!` or `execute-one!` call. The result logging function is the `execute!` or `execute-one!` call or an exception if the call
not called for the `plan` or `prepare` call (since they do not produce failed. The result logging function is not called for the `plan`
result sets directly). or `prepare` call (since they do not produce result sets directly).
Bear in mind that `get-datasource`, `get-connection`, and `with-transaction` Bear in mind that `get-datasource`, `get-connection`, and `with-transaction`
return plain Java objects, so if you call any of those on this wrapped return plain Java objects, so if you call any of those on this wrapped

View file

@ -32,14 +32,22 @@
(merge (:options this) opts))) (merge (:options this) opts)))
(-execute-one [this sql-params opts] (-execute-one [this sql-params opts]
(let [state ((:sql-logger this) 'next.jdbc/execute-one! sql-params)] (let [state ((:sql-logger this) 'next.jdbc/execute-one! sql-params)]
(doto (p/-execute-one (:connectable this) sql-params (try
(merge (:options this) opts)) (doto (p/-execute-one (:connectable this) sql-params
(result-logger-helper this 'next.jdbc/execute-one! state)))) (merge (:options this) opts))
(result-logger-helper this 'next.jdbc/execute-one! state))
(catch Throwable t
(result-logger-helper t this 'next.jdbc/execut-one! state)
(throw t)))))
(-execute-all [this sql-params opts] (-execute-all [this sql-params opts]
(let [state ((:sql-logger this) 'next.jdbc/execute! sql-params)] (let [state ((:sql-logger this) 'next.jdbc/execute! sql-params)]
(doto (p/-execute-all (:connectable this) sql-params (try
(merge (:options this) opts)) (doto (p/-execute-all (:connectable this) sql-params
(result-logger-helper this 'next.jdbc/execute! state))))) (merge (:options this) opts))
(result-logger-helper this 'next.jdbc/execute! state))
(catch Throwable t
(result-logger-helper t this 'next.jdbc/execut-one! state)
(throw t))))))
(extend-protocol p/Preparable (extend-protocol p/Preparable
SQLLogging SQLLogging