4

When writing my own interactive function, whats the best way to report that nothing happened.

(if line-is-empty
    (message "Found empty line, nothing to do!")
  (do-stuff))

Or is it better to use an error (even though it's not exactly an error, just that the command can't do anything useful).

(when line-is-empty
  (error "Found empty line, nothing to do!"))
(do-stuff)
3
  • I have the impression that user-error would be better in your case than just error if you eventually want to interpret it as an error.
    – Tobias
    Commented Nov 27, 2019 at 13:47
  • The question is primarily opinion-based, so it risks being closed. Depending on the exact context - including user or developer preferences, one or the other can provide better behavior.
    – Drew
    Commented Nov 27, 2019 at 15:55
  • I don't think this is opinion based, there are practical considerations for using error / message, it's not just personal preference.
    – ideasman42
    Commented Nov 27, 2019 at 16:11

2 Answers 2

3

The only thing to be considered here is the semantics.

One should use a programming language as good as possible in a sense of a natural language. I.e., the code you write should as directly express what you intent to do as possible. Only in very time-critical sections of the program one may strife from that path under the condition that one documents these deviations (including the cause of their necessity).

  1. If the thing you have is an error caused by miss-use of the command use user-error.
  2. If it is an abnormal state in the program use error or cl-assert.
  3. If it is just worth a warning use warn.
  4. If you want to notify the user about some trivial outcome of the command which does not show any visible effect otherwise use message.

All other aspects of the special forms and functions can be tailored to your needs with, e.g.,

  • (signal...)
  • (catch ... (throw...)...)
  • (cl-block...(throw...)...(cl-return)...)
  • (condition-case...)
  • (unwind-protect...)
  • and so on...
3
  • I'd add that it's important to consider that interactive functions can also be used non-interactively, so it's good practice to keep in mind that maybe your function was called from some other Elisp function when considering whether to signal an error or emit a message (or do nothing).
    – Stefan
    Commented Nov 27, 2019 at 18:54
  • Yes, @Stefan that are the technical details which jue already gave in his great answer. I don't repeat that here. The main message of my answer is that when you program you do not only speak to the machine. You speak to yourself maybe some years ahead, to others that want to contribute to your code, and maybe to the new maintainer when you get tired of your own code. Do whatever you can that that person understands your intention. The second part of the answer indicates that you can signal after a message and you can catch an error. So the technical details are not so important as they seem.
    – Tobias
    Commented Nov 27, 2019 at 21:31
  • @Stefan Add on to "you can signal after a message and you can catch an error". I don't want to say that you should do that. In fact you should avoid such wired constructs. Only use it if it expresses best what you are trying to say. The technique of catching errors is often used. I do not need to say anything about it. But, also signalling for other purposes than error indication is used in code shipped with Emacs. An example is the programmable completion stuff... or was it font-lock? Uff, now the comment already got out on accident. I actually wanted to add the example here...
    – Tobias
    Commented Nov 27, 2019 at 21:36
3

It depends on your usecase.


error signals an error, this means it rewinds the call stack until the previous condition-case which catches the error.

Consider following code:

(defun foo ()
  (interactive)
  (blah)
  (message "end1"))

(defun blah ()
  (error "Moep"))

"end1" will never be printed.


while message just logs the message and your code keeps running.


Also you should consider to message only if things really go wrong. This helps to reduce the noise at users interface.


Remark on error usage from documentation:

In Emacs, the convention is that error messages start with a capital letter but do not end with a period. Please follow this convention for the sake of consistency.

1
  • The OP explicitly speaks of an interactive command. In that case the error is caught in the command loop and your first argument weights only half as heavy as it appears at the first glance. But, in principle you are right. The interactive function might be used elsewhere in Elisp code even if it is intended for interactive use.
    – Tobias
    Commented Nov 27, 2019 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.