7

I am relatively new to emacs / elisp, and am trying to build some custom functionality.

I have added a number of functions which are added to a major-mode.

Occasionally (and seemingly only after a long while of running), the following warning message appears in the *Warnings* buffer:

Warning (emacs): recentf mode: Wrong type argument: stringp, nil

I am unsure as to what is causing it.

Is it possible to "catch" this error, and print a call stack so I can see where it's coming from?

Drew
  • 75,699
  • 9
  • 109
  • 225
Steve Lorimer
  • 545
  • 4
  • 13

1 Answers1

8

Use M-x set-variable RET debug-on-error RET t RET.

(Or M-: (setq debug-on-error t).)

That will open the debugger when the error is raised. You can see who called that recentf-mode, what arguments it was passed, etc.

The problem you see is that recentf-mode was expecting a string argument and it received a nil argument (or possibly no argument).

To debug problems in the execution of a function (e.g. recentf-mode) you can use M-x debug-on-entry RET recentf-mode RET. (That's not the problem here, presumably, but it's good to know.) That will open the debugger when function recentf-mode is invoked. You can step through the function using d or c.


Update after your comment:

Ah yes, my bad. I didn't notice that the message is a warning message and not an error message.

Looking at the code in recentf.el, I see this, which is apparently what produces that message:

(defun recentf-save-list ()
  "Save the recent list.
Write data into the file specified by `recentf-save-file'."
  (interactive)
  (condition-case error
      (with-temp-buffer
        (erase-buffer)
        (set-buffer-file-coding-system recentf-save-file-coding-system)
        (insert (format recentf-save-file-header (current-time-string)))
        (recentf-dump-variable 'recentf-list recentf-max-saved-items)
        (recentf-dump-variable 'recentf-filter-changer-current)
        (insert "\n\n;; Local Variables:\n"
                (format ";; coding: %s\n" recentf-save-file-coding-system)
                ";; End:\n")
        (write-file (expand-file-name recentf-save-file))
        (when recentf-save-file-modes
          (set-file-modes recentf-save-file recentf-save-file-modes))
        nil)
    (error
     (warn "recentf mode: %s" (error-message-string error)))))

So it apparently means that one of those actions led to an error (which was handled by displaying the warning message). Which of the actions led to the message is unclear. You'd have to check each of the functions, to see whether (a) it expects a string argument and (b) whether it was instead passed nil.

I'd suggest that you start with each of the variables recentf-save-* - see if one of them has value nil instead of a string.

You could also copy that function definition, change warn to error, and try again. Then the debug-on-error should kick in OK, so you can see better what the problem is.

Alternatively, you can do M-x debug-on-entry RET recentf-save-list RET, and walk through the debugger (using d) when that function is invoked, to see exactly what's going on. If you do that, evaluate the function definition again, from Lisp, so you get a better debugging session than if you just use the byte-compiled definition. To evaluate it, put your cursor inside it and use C-M-x (in Emacs-Lisp mode).

It's too bad that the warning message is not more helpful. The code be written better, to handle the error more appropriately. You might consider filing an Emacs bug report (aka enhancement request): M-x report-emacs-bug.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • 1
    Is `M-x set-variable RET debug-on-error RET t RET` any better than `M-x toggle-debug-on-error` ? – izkon Sep 29 '17 at 20:43
  • 1
    @izkon: they are equivalent assuming that you start from the `nil` state. Obviously, they are not equivalent if you start from the `t` state :-) – NickD Sep 29 '17 at 21:20
  • @Drew I turned on `debug-on-error` (and confirmed it is on with `describe-variable`). However, as of this morning, the error message has appeared a further 3 times, and the debugger hasn't appeared. – Steve Lorimer Oct 02 '17 at 14:22
  • Aha! See my update. It's a warning message, not an error message. – Drew Oct 02 '17 at 16:18
  • @Drew thanks for the update, much appreciated! – Steve Lorimer Oct 02 '17 at 16:38