[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/plz 9ac623858c 01/40: WIP: Fix nil return value bugs
From: |
ELPA Syncer |
Subject: |
[elpa] externals/plz 9ac623858c 01/40: WIP: Fix nil return value bugs |
Date: |
Mon, 26 Jun 2023 06:59:31 -0400 (EDT) |
branch: externals/plz
commit 9ac623858c07d046b386a750968e2f9436ee4502
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>
WIP: Fix nil return value bugs
---
plz.el | 148 ++++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 92 insertions(+), 56 deletions(-)
diff --git a/plz.el b/plz.el
index 48901e7a37..40c35050e7 100644
--- a/plz.el
+++ b/plz.el
@@ -405,28 +405,32 @@ NOQUERY is passed to `make-process', which see."
(decode (pcase as
('binary nil)
(_ decode)))
+ (default-directory temporary-file-directory)
+ (process-buffer (generate-new-buffer " *plz-request-curl*"))
+ (process (make-process :name "plz-request-curl"
+ :buffer process-buffer
+ :coding 'binary
+ :command (append (list plz-curl-program)
curl-command-line-args)
+ :connection-type 'pipe
+ :sentinel #'plz--sentinel
+ ;; FIXME: Set the stderr process sentinel to
ignore to prevent
+ ;; "process finished" garbage in the buffer
(response body). See:
+ ;;
<https://stackoverflow.com/questions/42810755/how-to-remove-process-finished-message-from-make-process-or-start-process-in-e>.
+ :stderr process-buffer
+ :noquery noquery))
sync-p)
(when (eq 'sync then)
(setf sync-p t
;; FIXME: For sync requests, `else' should be forced nil.
then (lambda (result)
+ (process-put process :plz-result result)
(setf plz-result result))))
- (with-current-buffer (generate-new-buffer " *plz-request-curl*")
+ (with-current-buffer process-buffer
;; Avoid making process in a nonexistent directory (in case the current
;; default-directory has since been removed). It's unclear what the best
;; directory is, but this seems to make sense, and it should still exist.
- (let ((default-directory temporary-file-directory)
- (process (make-process :name "plz-request-curl"
- :buffer (current-buffer)
- :coding 'binary
- :command (append (list plz-curl-program)
curl-command-line-args)
- :connection-type 'pipe
- :sentinel #'plz--sentinel
- ;; FIXME: Set the stderr process sentinel
to ignore to prevent
- ;; "process finished" garbage in the buffer
(response body). See:
- ;;
<https://stackoverflow.com/questions/42810755/how-to-remove-process-finished-message-from-make-process-or-start-process-in-e>.
- :stderr (current-buffer)
- :noquery noquery))
+ (let (
+
;; The THEN function is called in the response buffer.
(then (pcase-exhaustive as
((or 'binary 'string)
@@ -437,11 +441,17 @@ NOQUERY is passed to `make-process', which see."
(plz--narrow-to-body)
(when decode
(decode-coding-region (point) (point-max)
coding-system))
- (funcall then (buffer-string)))))
+ (let ((string (buffer-string)))
+ (unless string
+ (error "STRING IS NIL?! STRING:%S" string))
+ (funcall then string)))))
('buffer (lambda ()
(funcall then (current-buffer))))
('response (lambda ()
- (funcall then (plz--response :decode-p
decode))))
+ (let ((response (plz--response :decode-p
decode)))
+ (unless response
+ (error "RESPONSE IS NIL?!
BUFFER-CONTENTS:%S" (buffer-string)))
+ (funcall then response))))
('file (lambda ()
(set-buffer-multibyte nil)
(plz--narrow-to-body)
@@ -494,9 +504,21 @@ NOQUERY is passed to `make-process', which see."
;; According to the Elisp manual, blocking on a process's
;; output is really this simple. And it seems to work.
(accept-process-output process))
- (prog1 plz-result
- (unless (eq as 'buffer)
- (kill-buffer))))
+ (unless (process-get process :plz-result)
+ (plz--sentinel process "finished\n")
+ (unless (process-get process :plz-result)
+ (error "NO RESULT FROM PROCESS:%S BUFFER-STRING:%S" process
+ (buffer-string))))
+ (pcase (process-get process :plz-result)
+ ((pred plz-error-p)
+ ;; FIXME: ...signal correct error type
+ (if plz-else
+ (funcall plz-else (process-get process :plz-result))
+ (signal 'plz-http-error (process-get process :plz-result))))
+ (_
+ (prog1 (process-get process :plz-result) ;; plz-result
+ (unless (eq as 'buffer)
+ (kill-buffer))))))
process)))))
;;;;; Queue
@@ -697,45 +719,59 @@ node `(elisp) Sentinels'). Kills the buffer before
returning."
(unwind-protect
(with-current-buffer buffer
(setf sync plz-sync)
- (pcase-exhaustive status
- ((or 0 "finished\n")
- ;; Curl exited normally: check HTTP status code.
- (goto-char (point-min))
- (plz--skip-proxy-headers)
- (while (plz--skip-redirect-headers))
- (pcase (plz--http-status)
- ((and status (guard (<= 200 status 299)))
- ;; Any 2xx response is considered successful.
- (ignore status) ; Byte-compiling in Emacs <28 complains
without this.
- (funcall plz-then))
- ;; Any other status code is considered unsuccessful
- ;; (for now, anyway).
- (_ (let ((err (make-plz-error :response (plz--response))))
- (pcase-exhaustive plz-else
- (`nil (signal 'plz-http-error (list "plz--sentinel: HTTP
error" err)))
- ((pred functionp) (funcall plz-else err)))))))
-
- ((or (and (pred numberp) code)
- (rx "exited abnormally with code " (let code (group (1+
digit)))))
- ;; Curl error.
- (let* ((curl-exit-code (cl-typecase code
- (string (string-to-number code))
- (number code)))
- (curl-error-message (alist-get curl-exit-code
plz-curl-errors))
- (err (make-plz-error :curl-error (cons curl-exit-code
curl-error-message))))
+ (condition-case err
+ (pcase-exhaustive status
+ ((or 0 "finished\n")
+ ;; Curl exited normally: check HTTP status code.
+ (goto-char (point-min))
+ (plz--skip-proxy-headers)
+ (while (plz--skip-redirect-headers))
+ (pcase (plz--http-status)
+ ((and status (guard (<= 200 status 299)))
+ ;; Any 2xx response is considered successful.
+ (ignore status) ; Byte-compiling in Emacs <28 complains
without this.
+ (funcall plz-then))
+ (_
+ ;; Any other status code is considered unsuccessful
+ ;; (for now, anyway).
+ (let ((err (make-plz-error :response (plz--response))))
+ (process-put process-or-buffer :plz-result err)
+ (pcase-exhaustive plz-else
+ (`nil (setf plz-result err))
+ ((pred functionp) (funcall plz-else err)))))))
+
+ ((or (and (pred numberp) code)
+ (rx "exited abnormally with code " (let code (group (1+
digit)))))
+ ;; Curl error.
+ (let* ((curl-exit-code (cl-typecase code
+ (string (string-to-number code))
+ (number code)))
+ (curl-error-message (alist-get curl-exit-code
plz-curl-errors))
+ (err (make-plz-error :curl-error (cons curl-exit-code
curl-error-message))))
+ (process-put process-or-buffer :plz-result err)
+ (pcase-exhaustive plz-else
+ ;; FIXME: Returning a plz-error structure which has a
curl-error slot, wrapped in a plz-curl-error, is confusing.
+ (`nil (setf plz-result err))
+ ((pred functionp) (funcall plz-else err)))))
+
+ ((and (or "killed\n" "interrupt\n") status)
+ ;; Curl process killed or interrupted.
+ (let* ((message (pcase status
+ ("killed\n" "curl process killed")
+ ("interrupt\n" "curl process interrupted")))
+ (err (make-plz-error :message message)))
+ (process-put process-or-buffer :plz-result err)
+ (pcase-exhaustive plz-else
+ (`nil (setf plz-result err))
+ ((pred functionp) (funcall plz-else err))))))
+ (error
+ ;; Error signaled by a function called to process HTTP response:
+ ;; rather than signaling an error from within the sentinel,
+ ;; return or call the ELSE function with a plz-error struct.
+ (let ((err (make-plz-error :message (format "plz--sentinel: Error
signaled: %S" err))))
+ (process-put process-or-buffer :plz-result err)
(pcase-exhaustive plz-else
- ;; FIXME: Returning a plz-error structure which has a
curl-error slot, wrapped in a plz-curl-error, is confusing.
- (`nil (signal 'plz-curl-error (list "plz--sentinel: Curl
error" err)))
- ((pred functionp) (funcall plz-else err)))))
-
- ((and (or "killed\n" "interrupt\n") status)
- ;; Curl process killed or interrupted.
- (let* ((message (pcase status
- ("killed\n" "curl process killed")
- ("interrupt\n" "curl process interrupted")))
- (err (make-plz-error :message message)))
- (pcase-exhaustive plz-else
- (`nil (signal 'plz-curl-error (list "plz--sentinel: Curl
error" err)))
+ (`nil (setf plz-result err))
((pred functionp) (funcall plz-else err)))))))
(when finally
(funcall finally))
- [elpa] externals/plz updated (a8ae654530 -> 5e63662e21), ELPA Syncer, 2023/06/26
- [elpa] externals/plz 9ac623858c 01/40: WIP: Fix nil return value bugs,
ELPA Syncer <=
- [elpa] externals/plz 797963c035 02/40: WIP: Use separate buffer for STDERR, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 50d977288e 04/40: Fix: Set stderr process sentinel to #'ignore, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 0d4356640d 05/40: Change: Use only one error type, plz-error, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 046f29a816 08/40: Docs: Remove old TODO, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 81d1c61f1f 07/40: Tidy docstring and comment, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 56c92ff78e 12/40: Tidy, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 43231ac43c 14/40: WIP: Use timer for response parsing, ELPA Syncer, 2023/06/26
- [elpa] externals/plz d6dfe3b27a 11/40: Tidy: Remove plz-result, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 85ac0fbe38 15/40: WIP: Use sentinel value; add comments, ELPA Syncer, 2023/06/26
- [elpa] externals/plz 7d197e968a 20/40: Change: (plz--respond) Don't catch errors from THEN/ELSE, ELPA Syncer, 2023/06/26