From 42d53b25e5b36c08ed56c1b742aabc89587b8427 Mon Sep 17 00:00:00 2001 From: Karthik Chikmagalur Date: Wed, 22 Mar 2023 18:34:18 -0700 Subject: [PATCH] gptel: Handle insufficient quota and other errors * gptel.el (gptel--url-parse-response): Produce better error messages when using `url-retrieve'. This includes JSON parsing failures and insufficient quota messages. * gptel-curl.el (gptel-curl--parse-response): Produce better error messages when using curl. This includes JSON parsing failures and insufficient quota messages. --- gptel-curl.el | 32 ++++++++++++++++++++++---------- gptel.el | 32 +++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/gptel-curl.el b/gptel-curl.el index d304275..a4a3629 100644 --- a/gptel-curl.el +++ b/gptel-curl.el @@ -121,17 +121,29 @@ buffer." (match-string 1 http-msg)))) (json-object-type 'plist) (response (progn (goto-char header-size) - (json-read))) - (content (map-nested-elt - response '(:choices 0 :message :content)))) + (condition-case nil + (json-read) + (json-readtable-error 'json-read-error))))) (cond - ((not (equal http-status "200")) - (message "GPTChat request failed with code %s" http-status) - (list :content nil :status http-msg)) - (content - (list :content (string-trim content) :status http-msg)) - (t (message "Could not parse response from ChatGPT.") - (list :content nil :status http-msg)))))))) + ((equal http-status "200") + (list :content + (string-trim + (map-nested-elt response '(:choices 0 :message :content))) + :status http-msg)) + ((plist-get response :error) + (let* ((error-plist (plist-get response :error)) + (error-msg (plist-get error-plist :message)) + (error-type (plist-get error-plist :type))) + (message "ChatGPT error: %s" error-msg) + (list :content nil :status (concat http-msg ": " error-type)))) + ((eq response 'json-read-error) + (message "ChatGPT error: Malformed JSON in response.") + (list :content nil :status (concat http-msg ": Malformed JSON in response."))) + (t (message "ChatGPT error: Could not parse HTTP response.") + (list :content nil :status (concat http-msg ": Could not parse HTTP response.")))) + (message "ChatGPT error: Could not parse HTTP response.") + (list :content nil + :status (concat http-msg ": Could not parse HTTP response."))))))) (provide 'gptel-curl) ;;; gptel-curl.el ends here diff --git a/gptel.el b/gptel.el index 1961f89..58678f5 100644 --- a/gptel.el +++ b/gptel.el @@ -339,15 +339,33 @@ INFO is a plist with the following keys: (clone-buffer "*gptel-error*" 'show))) (with-current-buffer response-buffer (if-let* ((status (buffer-substring (line-beginning-position) (line-end-position))) - ((string-match-p "200 OK" status)) (json-object-type 'plist) (response (progn (forward-paragraph) - (json-read))) - (content (map-nested-elt - response '(:choices 0 :message :content)))) - (list :content (string-trim (decode-coding-string content 'utf-8)) - :status status) - (list :content nil :status status))))) + (condition-case nil + (json-read) + (json-readtable-error 'json-read-error))))) + (cond + ((string-match-p "200 OK" status) + (list :content (string-trim + (decode-coding-string + (content (map-nested-elt + response '(:choices 0 :message :content))) + 'utf-8)) + :status status)) + ((plist-get response :error) + (let* ((error-plist (plist-get response :error)) + (error-msg (plist-get error-plist :message)) + (error-type (plist-get error-plist :type))) + (message "ChatGPT error: %s" error-msg) + (list :content nil :status (concat status ": " error-type)))) + ((eq response 'json-read-error) + (message "ChatGPT error: Malformed JSON in response.") + (list :content nil :status (concat http-msg ": Malformed JSON in response."))) + (t (message "ChatGPT error: Could not parse HTTP response.") + (list :content nil :status (concat status ": Could not parse HTTP response.")))) + (message "ChatGPT error: Could not parse HTTP response.") + (list :content nil + :status (concat status ": Could not parse HTTP response.")))))) ;;;###autoload (defun gptel (name &optional api-key initial)