Improve general error handling at startup
This will hopefully reveal more information as to the cause and origin of errors at startup. It should also make doom-debug-mode more likely to produce a backtrace in non-interactive sessions.
This commit is contained in:
parent
c8aba6f552
commit
ab07e07352
6 changed files with 87 additions and 68 deletions
|
@ -251,5 +251,5 @@ init.el and config.el. Then runs `doom-reload-hook'."
|
|||
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
|
||||
(doom-initialize-modules 'force))
|
||||
(print! (green "%d packages reloaded" (length package-alist)))
|
||||
(run-hooks 'doom-reload-hook)
|
||||
(run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
|
||||
t))))
|
||||
|
|
|
@ -770,12 +770,9 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
total-ok (- (length target-files) total-noop)
|
||||
total-noop))))
|
||||
(error
|
||||
(print! (red "\n%%s\n\n%%s\n\n%%s")
|
||||
"There were breaking errors."
|
||||
(error-message-string ex)
|
||||
(print! (red "\n%s\n\n%%s" "There were breaking errors.")
|
||||
"Reverting changes...")
|
||||
(quiet! (doom-clean-byte-compiled-files))
|
||||
(print! (yellow "Finished (nothing was byte-compiled)"))))))))
|
||||
(signal 'doom-error (list 'byte-compile e))))))))
|
||||
|
||||
(defun doom-clean-byte-compiled-files ()
|
||||
"Delete all the compiled elc files in your Emacs configuration and private
|
||||
|
|
|
@ -27,6 +27,10 @@ A warning will be put out if these deprecated modules are used.")
|
|||
;; Bootstrap API
|
||||
;;
|
||||
|
||||
;; Custom errors
|
||||
(define-error 'doom-autoload-error "Error in your autoloads file(s)" 'doom-error)
|
||||
(define-error 'doom-private-error "Error in your private config" 'doom-error)
|
||||
|
||||
(defun doom-initialize-modules (&optional force-p)
|
||||
"Loads the init.el in `doom-private-dir' and sets up hooks for a healthy
|
||||
session of Dooming. Will noop if used more than once, unless FORCE-P is
|
||||
|
@ -36,16 +40,19 @@ non-nil."
|
|||
;; recurse by accident if any of them need `doom-initialize-modules'.
|
||||
(setq doom-init-modules-p t)
|
||||
(when doom-private-dir
|
||||
(condition-case e
|
||||
(load (expand-file-name "init" doom-private-dir)
|
||||
'noerror 'nomessage))))
|
||||
'noerror 'nomessage)
|
||||
(error (signal 'doom-private-error (list 'init e)))))))
|
||||
|
||||
(defun doom-initialize-autoloads (file)
|
||||
"Tries to load FILE (an autoloads file). Return t on success, nil otherwise."
|
||||
(condition-case-unless-debug e
|
||||
(condition-case e
|
||||
(load (file-name-sans-extension file) 'noerror 'nomessage)
|
||||
('error
|
||||
(message "Autoload error: %s -> %s"
|
||||
(car e) (error-message-string e)))))
|
||||
(if noninteractive
|
||||
(message "Autoload file warning: %s -> %s" (car e) (error-message-string e))
|
||||
(signal 'doom-autoload-error e)))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -289,13 +296,15 @@ to least)."
|
|||
`(let (file-name-handler-alist)
|
||||
(setq doom-modules ',doom-modules)
|
||||
,@(nreverse init-forms)
|
||||
(run-hooks 'doom-init-hook)
|
||||
(run-hook-wrapped 'doom-init-hook #'doom-try-run-hook)
|
||||
(unless noninteractive
|
||||
(let ((doom--stage 'config))
|
||||
,@(nreverse config-forms)
|
||||
(when doom-private-dir
|
||||
(condition-case e
|
||||
(load ,(expand-file-name "config" doom-private-dir)
|
||||
t (not doom-debug-mode))))))))
|
||||
t (not doom-debug-mode))
|
||||
(error (signal 'doom-private-error (list 'config e))))))))))
|
||||
|
||||
(defvar doom-disabled-packages)
|
||||
(defmacro def-package! (name &rest plist)
|
||||
|
|
|
@ -110,31 +110,20 @@ them."
|
|||
(error "Could not initialize quelpa"))))
|
||||
|
||||
(when (or force-p (not doom-packages))
|
||||
(let ((doom-modules (doom-modules)))
|
||||
(setq doom-packages nil)
|
||||
(cl-flet
|
||||
((_load
|
||||
(file &optional noerror)
|
||||
(condition-case-unless-debug ex
|
||||
(load file noerror 'nomessage 'nosuffix)
|
||||
('error
|
||||
(lwarn 'doom-initialize-packages :warning
|
||||
"%s in %s: %s"
|
||||
(car ex)
|
||||
(file-relative-name file doom-emacs-dir)
|
||||
(error-message-string ex))))))
|
||||
(let ((doom--stage 'packages)
|
||||
(let ((doom-modules (doom-modules))
|
||||
(doom--stage 'packages)
|
||||
(noninteractive t))
|
||||
(_load (expand-file-name "packages.el" doom-core-dir))
|
||||
(setq doom-packages nil)
|
||||
(load (expand-file-name "packages.el" doom-core-dir) t t)
|
||||
;; We load the private packages file twice to ensure disabled
|
||||
;; packages are seen ASAP, and a second time to ensure privately
|
||||
;; overridden packages are properly overwritten.
|
||||
(let ((private-packages (expand-file-name "packages.el" doom-private-dir)))
|
||||
(_load private-packages t)
|
||||
(load private-packages t t)
|
||||
(cl-loop for key being the hash-keys of doom-modules
|
||||
for path = (doom-module-path (car key) (cdr key) "packages.el")
|
||||
do (let ((doom--current-module key)) (_load path t)))
|
||||
(_load private-packages t)))))))))
|
||||
do (let ((doom--current-module key)) (load path t t)))
|
||||
(load private-packages t t)))))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -202,6 +191,7 @@ Returns t if package is successfully registered, and nil if it was disabled
|
|||
elsewhere."
|
||||
(declare (indent defun))
|
||||
(doom--assert-stage-p 'packages #'package!)
|
||||
(condition-case e
|
||||
(let* ((old-plist (cdr (assq name doom-packages)))
|
||||
(pkg-recipe (or (plist-get plist :recipe)
|
||||
(and old-plist (plist-get old-plist :recipe))))
|
||||
|
@ -226,7 +216,10 @@ elsewhere."
|
|||
`(progn
|
||||
,(if pkg-pin `(map-put package-pinned-packages ',name ,pkg-pin))
|
||||
(map-put doom-packages ',name ',plist)
|
||||
(not (memq ',name doom-disabled-packages)))))
|
||||
(not (memq ',name doom-disabled-packages))))
|
||||
(error
|
||||
(signal 'doom-private-error
|
||||
(list (list 'packages name) e)))))
|
||||
|
||||
(defmacro packages! (&rest packages)
|
||||
"A convenience macro like `package!', but allows you to declare multiple
|
||||
|
|
|
@ -724,7 +724,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
;; Ensure ansi codes in compilation buffers are replaced
|
||||
(add-hook 'compilation-filter-hook #'doom|compilation-ansi-color-apply)
|
||||
;;
|
||||
(run-hooks 'doom-init-ui-hook))
|
||||
(run-hook-wrapped 'doom-init-ui-hook #'doom-try-run-hook))
|
||||
|
||||
(add-hook 'doom-post-init-hook #'doom|init-ui)
|
||||
|
||||
|
|
26
core/core.el
26
core/core.el
|
@ -115,6 +115,14 @@ else (except for `window-setup-hook').")
|
|||
(defvar doom--stage 'init)
|
||||
|
||||
|
||||
;;
|
||||
;; Custom error types
|
||||
;;
|
||||
|
||||
(define-error 'doom-error "Doom Emacs error")
|
||||
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
||||
|
||||
|
||||
;;
|
||||
;; Emacs core configuration
|
||||
;;
|
||||
|
@ -231,6 +239,17 @@ original value of `symbol-file'."
|
|||
;; Bootstrap helpers
|
||||
;;
|
||||
|
||||
(defun doom-try-run-hook (hook)
|
||||
"Run HOOK (a hook function), but marks thrown errors to make it a little
|
||||
easier to tell where the came from.
|
||||
|
||||
Meant to be used with `run-hook-wrapped'."
|
||||
(condition-case e
|
||||
(funcall hook)
|
||||
(error (signal 'doom-hook-error (list hook e))))
|
||||
;; return nil so `run-hook-wrapped' won't short circuit
|
||||
nil)
|
||||
|
||||
(defun doom-ensure-same-emacs-version-p ()
|
||||
"Check if the running version of Emacs has changed and set
|
||||
`doom-emacs-changed-p' if it has."
|
||||
|
@ -274,16 +293,17 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
|
||||
(defun doom|post-init ()
|
||||
"Run `doom-post-init-hook'. That's all."
|
||||
(run-hooks 'doom-post-init-hook))
|
||||
(run-hook-wrapped 'doom-post-init-hook #'doom-try-run-hook))
|
||||
|
||||
(defun doom|run-all-startup-hooks ()
|
||||
"Run all startup Emacs hooks. Meant to be executed after starting Emacs with
|
||||
-q or -Q, for example:
|
||||
|
||||
emacs -Q -l init.el -f doom|run-all-startup-hooks"
|
||||
(run-hooks 'after-init-hook 'delayed-warnings-hook
|
||||
(mapc #'doom-try-run-hook
|
||||
(list 'after-init-hook 'delayed-warnings-hook
|
||||
'emacs-startup-hook 'term-setup-hook
|
||||
'window-setup-hook))
|
||||
'window-setup-hook)))
|
||||
|
||||
|
||||
;;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue