Improve MS SQL error handling when reading from source.

In particular, protect the sysdb-data-to-lisp routine, that calls into
CFFI and character decodings, with a restart-case allowing the calling
code to just ignore errors on a particular column by skipping it and
using nil instead (or something else if needed).
This commit is contained in:
Dimitri Fontaine 2014-12-22 18:32:11 +01:00
parent 46be4a58b7
commit f323625738
2 changed files with 20 additions and 5 deletions

View File

@ -113,10 +113,19 @@
:until (= rtc +no-more-rows+)
:do (let ((row (make-array (%dbnumcols %dbproc))))
(loop :for i :from 1 :to (%dbnumcols %dbproc)
:for value := (sysdb-data-to-lisp %dbproc
(%dbdata %dbproc i)
(%dbcoltype %dbproc i)
(%dbdatlen %dbproc i))
:for value
:= (restart-case
(sysdb-data-to-lisp %dbproc
(%dbdata %dbproc i)
(%dbcoltype %dbproc i)
(%dbdatlen %dbproc i))
(use-nil ()
:report "skip this column's value and use nil instead."
nil)
(use-empty-string ()
:report "skip this column's value and use empty-string instead."
"")
(use-value (value) value))
:do (setf (aref row (- i 1)) value))
(funcall row-fn row))))

View File

@ -66,7 +66,13 @@
(funcall process-row-fn row))))
(log-message :debug "~a" sql)
(handler-case
(mssql::map-query-results sql :row-fn row-fn :connection *mssql-db*)
(handler-bind
((condition
#'(lambda (c)
(log-message :error "~a" c)
(pgstate-incf *state* (target mssql) :errs 1)
(invoke-restart 'mssql::use-nil))))
(mssql::map-query-results sql :row-fn row-fn :connection *mssql-db*))
(condition (e)
(progn
(log-message :error "~a" e)