From: Joe Corneli
Subject: totally ignoring database error?
Date: 
Message-ID: <04929e4a-4b17-476d-97f7-91acbde63f06@f47g2000hsd.googlegroups.com>
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!
From: Kalle Olavi Niemitalo
Subject: Re: totally ignoring database error?
Date: 
Message-ID: <87ejcmnkt9.fsf@Astalo.kon.iki.fi>
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.