I am not a pro on the exception handling system. I think my question
is easy.
I wrote the following code that handles errors that arise when
duplicate strings are added to my database via CLSQL.
(defun add-string (text)
"Add a new string to the strings table."
(handler-bind ((sql-database-data-error
#'(lambda (condition)
(declare (ignore condition))
(warn "\"~A\" already exists." text)
(abort))))
(insert-records :into [strings]
:attributes '(text)
:values `(,text))
(add-record (string-present-p text) 0)))
Just as expected, when a duplicate string is provided, the code aborts
evaluation, e.g.:
(add-string "Introduction")
WARNING: "Introduction" already exists.
; Evaluation aborted.
My problem is, if I run the code synchronously through SLIME, I get
the message "Synchronous Lisp Evaluation aborted", and SLIME itself
aborts. This can derail a much larger process.
So, I'd like to handle the error without aborting, or anyway, without
bothering SLIME.
Any advice is appreciated!
Joe Corneli <·············@gmail.com> writes:
> (defun add-string (text)
> "Add a new string to the strings table."
> (handler-bind ((sql-database-data-error
> #'(lambda (condition)
> (declare (ignore condition))
> (warn "\"~A\" already exists." text)
> (abort))))
If you want the error handler to return from ADD-STRING,
rather than call a surrounding ABORT restart, I think you can
just replace the (abort) with (return-from add-string).
However, HANDLER-CASE would be more convenient here:
(defun add-string (text)
"Add a new string to the strings table."
(handler-case (progn
(insert-records :into [strings]
:attributes '(text)
:values `(,text))
(add-record (string-present-p text) 0))
(sql-database-data-error ()
(warn "\"~A\" already exists." text))))
I didn't test this though as I don't have CLSQL here.