Refactor error handling in package management API

I am hoping this will improve the ambiguous errors that originate from
package.el or quelpa.el.
This commit is contained in:
Henrik Lissner 2018-06-07 17:59:23 +02:00
parent 7e7b6fd8a6
commit ee262e7737
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -16,18 +16,14 @@
(defmacro doom--condition-case! (&rest body) (defmacro doom--condition-case! (&rest body)
`(condition-case-unless-debug ex `(condition-case-unless-debug ex
(condition-case ex2 (progn ,@body)
(progn ,@body)
('file-error
(print! (bold (red " FILE ERROR: %s" (error-message-string ex2))))
(print! " Trying again...")
(quiet! (doom-refresh-packages-maybe t))
,@body))
('user-error ('user-error
(print! (bold (red " ERROR: %s" ex)))) (print! (bold (red " NOTICE: %s" ex))))
('error ('file-error
(doom--refresh-pkg-cache) (print! (bold (red " FILE ERROR: %s" (error-message-string ex2))))
(print! (bold (red " FATAL ERROR: %s" ex)))))) (print! " Trying again...")
(quiet! (doom-refresh-packages-maybe t))
,@body)))
(defun doom--refresh-pkg-cache () (defun doom--refresh-pkg-cache ()
"Clear the cache for `doom-refresh-packages-maybe'." "Clear the cache for `doom-refresh-packages-maybe'."
@ -60,7 +56,7 @@
(defun doom-package-backend (name &optional noerror) (defun doom-package-backend (name &optional noerror)
"Get which backend the package NAME was installed with. Can either be elpa or "Get which backend the package NAME was installed with. Can either be elpa or
quelpa. Throws an error if NOERROR is nil and the package isn't installed." quelpa. Throws an error if NOERROR is nil and the package isn't installed."
(cl-assert (symbolp name) t) (cl-check-type name symbol)
(cond ((assq name quelpa-cache) (cond ((assq name quelpa-cache)
'quelpa) 'quelpa)
((assq name package-alist) ((assq name package-alist)
@ -75,7 +71,7 @@ quelpa. Throws an error if NOERROR is nil and the package isn't installed."
"Determine whether NAME (a symbol) is outdated or not. If outdated, returns a "Determine whether NAME (a symbol) is outdated or not. If outdated, returns a
list, whose car is NAME, and cdr the current version list and latest version list, whose car is NAME, and cdr the current version list and latest version
list of the package." list of the package."
(cl-assert (symbolp name) t) (cl-check-type name symbol)
(when-let* ((desc (cadr (assq name package-alist)))) (when-let* ((desc (cadr (assq name package-alist))))
(let* ((old-version (package-desc-version desc)) (let* ((old-version (package-desc-version desc))
(new-version (new-version
@ -100,15 +96,16 @@ list of the package."
;;;###autoload ;;;###autoload
(defun doom-package-prop (name prop) (defun doom-package-prop (name prop)
"Return PROPerty in NAME's plist." "Return PROPerty in NAME's plist."
(cl-assert (symbolp name) t) (cl-check-type name symbol)
(cl-assert (keywordp prop) t) (cl-check-type prop keyword)
(plist-get (cdr (assq name doom-packages)) prop)) (plist-get (cdr (assq name doom-packages)) prop))
;;;###autoload ;;;###autoload
(defun doom-package-different-backend-p (name) (defun doom-package-different-backend-p (name)
"Return t if a package named NAME (a symbol) has a new backend than what it "Return t if a package named NAME (a symbol) has a new backend than what it
was installed with. Returns nil otherwise, or if package isn't installed." was installed with. Returns nil otherwise, or if package isn't installed."
(cl-assert (symbolp name) t) (cl-check-type name symbol)
(doom-initialize-packages)
(and (package-installed-p name) (and (package-installed-p name)
(let* ((plist (cdr (assq name doom-packages))) (let* ((plist (cdr (assq name doom-packages)))
(old-backend (doom-package-backend name 'noerror)) (old-backend (doom-package-backend name 'noerror))
@ -119,7 +116,7 @@ was installed with. Returns nil otherwise, or if package isn't installed."
(defun doom-package-different-recipe-p (name) (defun doom-package-different-recipe-p (name)
"Return t if a package named NAME (a symbol) has a different recipe than it "Return t if a package named NAME (a symbol) has a different recipe than it
was installed with." was installed with."
(cl-assert (symbolp name) t) (cl-check-type name symbol)
(when (package-installed-p name) (when (package-installed-p name)
(let ((quelpa-recipe (assq name quelpa-cache)) (let ((quelpa-recipe (assq name quelpa-cache))
(doom-recipe (assq name doom-packages))) (doom-recipe (assq name doom-packages)))
@ -153,14 +150,17 @@ If INSTALLED-ONLY-P, only return packages that are installed."
;;;###autoload ;;;###autoload
(defun doom-get-depending-on (name) (defun doom-get-depending-on (name)
"Return a list of packages that depend on the package named NAME." "Return a list of packages that depend on the package named NAME."
(cl-check-type name symbol)
(when (package-built-in-p name) (when (package-built-in-p name)
(error "Can't get the dependency tree for built-in packages")) (error "Can't get the dependency tree for built-in packages"))
(when-let* ((desc (cadr (assq name package-alist)))) (if-let* ((desc (cadr (assq name package-alist))))
(mapcar #'package-desc-name (package--used-elsewhere-p desc nil t)))) (mapcar #'package-desc-name (package--used-elsewhere-p desc nil t))
(error "Couldn't find %s, is it installed?" name)))
;;;###autoload ;;;###autoload
(defun doom-get-dependencies-for (name &optional only) (defun doom-get-dependencies-for (name &optional only)
"Return a list of dependencies for a package." "Return a list of dependencies for a package."
(cl-check-type name symbol)
(when (package-built-in-p name) (when (package-built-in-p name)
(error "Can't get the dependency tree for built-in packages")) (error "Can't get the dependency tree for built-in packages"))
(package--get-deps name only)) (package--get-deps name only))
@ -262,6 +262,7 @@ Used by `doom//packages-install'."
(defun doom-install-package (name &optional plist) (defun doom-install-package (name &optional plist)
"Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an "Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an
example; the package name can be omitted)." example; the package name can be omitted)."
(cl-check-type name symbol)
(doom-initialize-packages) (doom-initialize-packages)
(when (and (package-installed-p name) (when (and (package-installed-p name)
(not (package-built-in-p name))) (not (package-built-in-p name)))
@ -286,6 +287,8 @@ example; the package name can be omitted)."
(defun doom-update-package (name &optional force-p) (defun doom-update-package (name &optional force-p)
"Updates package NAME (a symbol) if it is out of date, using quelpa or "Updates package NAME (a symbol) if it is out of date, using quelpa or
package.el as appropriate." package.el as appropriate."
(cl-check-type name symbol)
(doom-initialize-packages)
(unless (package-installed-p name) (unless (package-installed-p name)
(user-error "%s isn't installed" name)) (user-error "%s isn't installed" name))
(when (doom-package-different-backend-p name) (when (doom-package-different-backend-p name)
@ -294,10 +297,10 @@ package.el as appropriate."
(let ((inhibit-message (not doom-debug-mode)) (let ((inhibit-message (not doom-debug-mode))
(desc (cadr (assq name package-alist)))) (desc (cadr (assq name package-alist))))
(pcase (doom-package-backend name) (pcase (doom-package-backend name)
('quelpa (`quelpa
(let ((quelpa-upgrade-p t)) (let ((quelpa-upgrade-p t))
(quelpa (assq name quelpa-cache)))) (quelpa (assq name quelpa-cache))))
('elpa (`elpa
(let* ((archive (cadr (assq name package-archive-contents))) (let* ((archive (cadr (assq name package-archive-contents)))
(packages (packages
(if (package-desc-p archive) (if (package-desc-p archive)
@ -313,6 +316,8 @@ package.el as appropriate."
;;;###autoload ;;;###autoload
(defun doom-delete-package (name &optional force-p) (defun doom-delete-package (name &optional force-p)
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'." "Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
(cl-check-type name symbol)
(doom-initialize-packages)
(unless (package-installed-p name) (unless (package-installed-p name)
(user-error "%s isn't installed" name)) (user-error "%s isn't installed" name))
(let ((inhibit-message (not doom-debug-mode)) (let ((inhibit-message (not doom-debug-mode))
@ -322,7 +327,8 @@ package.el as appropriate."
(quelpa-save-cache) (quelpa-save-cache)
(setq quelpa-p t)) (setq quelpa-p t))
(package-delete (cadr (assq name package-alist)) force-p) (package-delete (cadr (assq name package-alist)) force-p)
(unless (package-installed-p name) (when (or (not (package-installed-p name))
(package-built-in-p name))
(let ((pkg-build-dir (expand-file-name (symbol-name name) quelpa-build-dir))) (let ((pkg-build-dir (expand-file-name (symbol-name name) quelpa-build-dir)))
(when (and quelpa-p (file-directory-p pkg-build-dir)) (when (and quelpa-p (file-directory-p pkg-build-dir))
(delete-directory pkg-build-dir t))) (delete-directory pkg-build-dir t)))