The context of my question: I was editing some clojure code, and point was inside a comment, and to the right of three characters: `abc'.

I ran the command: M-x company-diag, to ask company mode for a diagnosis of the current company configuration.

Emacs entered the debugger. My question is: Why did emacs enter the debugger?

From the documentation for debug-on-error:

Non-nil means enter debugger if an error is signaled.
Does not apply to errors handled by ‘condition-case’ or those
matched by ‘debug-ignored-errors’.

Although the value of debug-on-error is t, the code which signals the error is wrapped in a condition-case. Why didn't this wrapper prevent the debugger from being entered?

Here is the stack trace. Note that I have annotated this stack trace to indicate the condition case wrapping.

Debugger entered--Lisp error: (void-function clojure\.lang\.ExceptionInfo:)
  clojure\.lang\.ExceptionInfo:("abc" nil t)
  all-completions("abc" clojure\.lang\.ExceptionInfo: nil)
  completion-pcm--all-completions("" ("abc" point) clojure\.lang\.ExceptionInfo: nil)
  completion-basic-all-completions("abc" clojure\.lang\.ExceptionInfo: nil 3)
  #f(compiled-function (style) #<bytecode 0x1f03af9>)(basic)
  completion--some(#f(compiled-function (style) #<bytecode 0x1f03af9>) (basic partial-completion emacs22))
  completion--nth-completion(2 "abc" clojure\.lang\.ExceptionInfo: nil 3 (metadata))
  completion-all-completions("abc" clojure\.lang\.ExceptionInfo: nil 3 (metadata))
  company-capf(candidates "abc")
  apply(company-capf (candidates "abc"))
  company-call-backend-raw(candidates "abc")
  apply(company-call-backend-raw (candidates "abc"))
  company--force-sync(company-call-backend-raw (candidates "abc") company-capf)
  --> WRAPPED IN A CONDITION-CASE company-call-backend(candidates "abc")
  call-interactively(company-diag record nil)
  command-execute(company-diag record)
  ivy-read("M-x " [dap-go-delve-path hasNextPage diary-included-files usages bmkp-file-this-dir-some-tags-jump-other-window dap-ui-breakpoint-log-message bmkp-tags-map csv-transpose gdb-script-syntax-propertize-function avy-words counsel-alias-expand magit-reflog-commit treemacs-project->path-status duplicate magit-wip-buffer-backed-up diredp-wrap-around-flag LOCALP woman-last-file-name none-but-delete js2-property-flag js2-visit-computed-prop-name-node sgml-syntax-propertize gdb-frame-locals-buffer local-only cl-print--preprocess \.frames clojure-docstring-fill-column dap-python--test-class-p HTMLTableSectionElement lsp:signature-help-active-signature\? js2-EXPORT js2-block-node-len cljr--cljc-file-p being omt one include-omitted-p org-duration-format epl-installed-packages \' :name-match bmkp-non-invokable-alist-only lsp--virtual-buffer-mappings js2-var-decl-node-pos--cmacro sessions magit-diff-wash-hunk we-thinkers-history-log define-mode-local-override lispy-bind-variable Move\ out\ of\ sexp ...] :predicate #f(compiled-function (sym) #<bytecode 0x1f1126d>) :require-match t :history counsel-M-x-history :action counsel-M-x-action :keymap (keymap (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x)
  call-interactively(counsel-M-x nil nil)

Emacs is entering the debugger despite the fact that the call to company-call-backend is wrapped in condition-case:

(condition-case nil
            (setq cc (company-call-backend 'candidates (company--prefix-str prefix))
                   (lambda (c) (cons c (company-call-backend 'annotation c)))
          (error (setq annotations 'error)))
  • What happens if you use condition-case-no-debug or condition-case-unless-debug?
    – Drew
    Jun 4, 2021 at 18:53

1 Answer 1


Following from Drew's suggestion in the comments, we can see that company.el is using condition-case-unless-debug in a number of places, including in company-call-backend-raw -- which in your stack trace is being called after that "WRAPPED IN A CONDITION-CASE" company-call-backend call.

(condition-case-unless-debug VAR BODYFORM &rest HANDLERS)

Like ‘condition-case’ except that it does not prevent debugging.
More specifically if ‘debug-on-error’ is set then the debugger will be invoked
even if this catches the signal.

Your Answer

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

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