Skip to content

Commit

Permalink
Log errors that occur during init instead of entering debugger.
Browse files Browse the repository at this point in the history
  • Loading branch information
chaosemer committed Nov 21, 2023
1 parent 286f124 commit a580128
Showing 1 changed file with 52 additions and 30 deletions.
82 changes: 52 additions & 30 deletions init-dir.el
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@
;; load. Display would also have an easy way to reload that file and
;; get new perf data.
;;
;; Improve debug messages -- ideally instead of dropping into the
;; Emacs debugger, we would skip loading the rest of the file but know
;; the exact line that errored.
;; Improve error messages during load -- Add a link to the location of
;; the read error or the form being evaluated.
;;
;; Improve package debugging -- if selected packages were unable to be
;; activated (indicating they're not installed) display a helpful
Expand Down Expand Up @@ -87,6 +86,9 @@ disable the long load warning.
Also see `init-dir-load'.")

(defvar init-dir--error-and-warning-list '()
"Errors and warnings that came up while running `init-dir-load'.")

;;; The core functionality.
;;;###autoload
(defun init-dir-load (&optional dir)
Expand All @@ -111,34 +113,54 @@ This will display warnings whenever loading a single file from
the takes longer than `init-dir--long-load-time-warning'. See
its documentation to see how to handle files known to take a long
time to load."
(setq dir (or dir (expand-file-name "init" user-emacs-directory)))

(setq dir (or dir (expand-file-name "init" user-emacs-directory))
init-dir--error-and-warning-list '())

(mapc #'init-dir--load-single-file
(delete-dups
(mapcar #'file-name-sans-extension
(init-dir--directory-files-filter
dir
#'init-dir--file-init-loadable-p
t))))

;; Display any warnings.
(when init-dir--error-and-warning-list
(dolist (message (nreverse init-dir--error-and-warning-list))
(display-warning 'init message))))

(defun init-dir--load-single-file (file)
"Load a single file, with additional structure around it."

Check failure on line 133 in init-dir.el

View workflow job for this annotation

GitHub Actions / test (28.1, true)

Argument ‘file’ should appear (as FILE) in the doc string

Check failure on line 133 in init-dir.el

View workflow job for this annotation

GitHub Actions / test (28.2, true)

Argument ‘file’ should appear (as FILE) in the doc string

Check failure on line 133 in init-dir.el

View workflow job for this annotation

GitHub Actions / test (29.1, true)

Argument ‘file’ should appear (as FILE) in the doc string
(let ((prev-time (time-convert nil 'list))
(timing-messages '()))
(dolist (file (delete-dups
(mapcar #'file-name-sans-extension
(init-dir--directory-files-filter
dir
#'init-dir--file-init-loadable-p
t))))
(let ((debug-ignored-errors '())
(debug-on-error t)
(debug-on-quit t)
(init-dir--long-load-time-warning init-dir--long-load-time-warning))
(load file)
(let* ((cur-time (time-convert nil 'list))
(delta-time (float-time (time-subtract cur-time prev-time))))
(when (and init-dir--long-load-time-warning
(> delta-time init-dir--long-load-time-warning))
(push (format "Loading `%s' took %f seconds."
file delta-time)
timing-messages))
(setf prev-time cur-time))))

;; Helpful debugging for init files.
(when timing-messages
(dolist (message (nreverse timing-messages))
(display-warning 'init message)))))
(debug-ignored-errors '())
(debug-on-error t)
(debugger #'init-dir--debugger)
;; Dynamic binding intended to be modified by clients.
(init-dir--long-load-time-warning init-dir--long-load-time-warning))

(let* (;; This line actually loads the file as a side effect.
(load-error (catch 'init-dir--load-error (load file) nil))

(cur-time (time-convert nil 'list))
(delta-time (float-time (time-subtract cur-time prev-time))))
(when load-error
(push (format "Loading `%s' had an error: %S"
file (error-message-string load-error))
init-dir--error-and-warning-list))
(when (and init-dir--long-load-time-warning
(> delta-time init-dir--long-load-time-warning))
(push (format "Loading `%s' took %f seconds."
file delta-time)
init-dir--error-and-warning-list)))))

(defun init-dir--debugger (&rest args)
"Replacement debugger function while running `init-dir--load-single-file'."

Check failure on line 157 in init-dir.el

View workflow job for this annotation

GitHub Actions / test (28.1, true)

Argument ‘args’ should appear (as ARGS) in the doc string

Check failure on line 157 in init-dir.el

View workflow job for this annotation

GitHub Actions / test (28.2, true)

Argument ‘args’ should appear (as ARGS) in the doc string

Check failure on line 157 in init-dir.el

View workflow job for this annotation

GitHub Actions / test (29.1, true)

Argument ‘args’ should appear (as ARGS) in the doc string
(message "debugger: %S, %S" args (eq (car-safe args) 'error))
(if (eq (car-safe args) 'error)
;; This entered the debugger due to an error -- the exact case
;; we want to handle specially.
(throw 'init-dir--load-error (car-safe (cdr-safe args)))
(apply #'debug args)))

(provide 'init-dir)

Expand Down

0 comments on commit a580128

Please sign in to comment.