Alternative to HANDLER-CASE which is not a macro

So, consider the following code:

(define-condition some-condition (error) nil)

(defmethod print-object ((obj some-condition) stream)
  (format stream "HELLO THERE"))

(defmacro error-report-test-aux (fn-to-cause-error error-type-to-catch fn-to-handle-error expected-message)
  `(let ((result-message
           (handler-case (funcall ,fn-to-cause-error)
             (,error-type-to-catch (e) (funcall ,fn-to-handle-error e)))))
     (assert (string= result-message
                      ,expected-message))
     t))

      

I can use it like this:

(error-report-test-aux (lambda () (error 'some-condition)) 
                       some-condition 
                       #'princ-to-string 
                       "HELLO THERE")

      

But I wanted to make a error-report-test-aux

function instead of a macro, so that I can pass it the type of the condition inside the variable.

To just write defun

instead defmacro

and remove backquote and commas don't work because it handler-case

is a macro and doesn't evaluate error-type-to-catch

.

My question is: Is there something like handler-case

that that will evaluate its arguments (specifically the condition type argument)?

+3


source to share


1 answer


Yes and no: -)

No to your exact question

There is no standard function that does what you want, because trap errors require bindings to be set, and it is usually required to bind constant characters (like in / ) because it is easier to optimize. let

let*

You might consider creating a "generic" handler with handler-bind

and then abandoning the handling of "uninteresting" conditions (as suggested by @jkiiski in the comments), but I'm not sure if this suits your exact requirements (untested!):

(defun error-report-test-aux (fn-to-cause-error error-type-to-catch expected-message)
  (catch 'trap
    (handler-bind ((error
                    (lambda (condition)
                      (when (typep condition error-type-to-catch)
                        (throw 'trap (string= (princ-to-string condition)
                                              expected-message))))))
      (funcall fn-to-cause-error))))

      



Yes, implementation specific

IF your implementation implements handler-case

/ handler-bind

by binding an internal global variable you can use progv

to bind it yourself and thus implement yours error-report-test-aux

as a function.

This is probably not the best idea (your code is implementation specific).

Yes, kind

You can use the fact that some-condition

the CLOS class calls and uses common functions instead of macros.

+5


source







All Articles