What is the best way to catch error in elisp

I am trying to increase the etags-select functions so that it returns to the normal find tag if find-tag at the point failed. The code I tried is:

(defun my-etags-find-tag () "Find at point or fall back" (interactive) (unless (etags-select-find-tag-at-point) (etags-select-find-tag))) (global-set-key (kbd "Cf") 'my-etags-find-tag) 

However, this fails if the dot does not match a valid tag. Instead, I get an error caused by etags-select-find-tag-at-point:

 etags-select-find-tag-at-point: Wrong type argument: char-or-string-p, nil 

In this case, I just need to repeat the test executed by etags-select-find-tag-at-point:

 (defun my-etags-find-tag () "Find at point or fall back" (interactive) (if (find-tag-default) (etags-select-find-tag-at-point) (etags-select-find-tag))) 

But that seems a little redundant. Is it possible to catch exceptions and perform alternative processing in elisp?

+4
source share
2 answers

Try ignore-errors ; eg,

 (unless (ignore-errors (etags-select-find-tag-at-point)) (etags-select-find-tag)) 

Usually (ignore-errors body) returns all body ; when an error occurs, it returns nil .

See also condition-case for more general handling of conditions.

If you have the Elisp reference manual installed, you can get more detailed information from Ch S ignore-errors .

Edit:

I could not consider the possibility that the function could return zero for success; so we probably need

 (unless (ignore-errors (or (etags-select-find-tag-at-point) t)) (etags-select-find-tag)) 
+9
source

Without changing the source code of etags-select.el , I find it more reasonable, even if it calls find-tag-default twice. You can trick the dynamic environment into a call to avoid repeating the call by memoizing it with something like:

 (defun my-etags-find-tag () "Find at point or fall back" (interactive) (let ((ftd (find-tag-default))) (flet ((find-tag-default () ftd)) (if (find-tag-default) (etags-select-find-tag-at-point) (etags-select-find-tag))))) 

EDIT : OK, according to your request, an explanation of the code. First, note that this code fulfills both questions:

  • This does not fail.
  • It is more efficient than the code you show (the one that you say is redundant).

Why is it more effective? The problem with your redundant code is that you call find-tag-default to see if it is nil , and if so, you call etags-select-find-tag-at-point . This function again calls find-tag-default to get the find-tag-default value. What my code does is to cache the find-tag-default value by overriding the function, counting only the calculated value. flet does this, so when etags-select-find-tag-at-point calls find-tag-default , the computed value is returned without further processing.

+4
source

All Articles