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.
This commit is contained in:
Karthik Chikmagalur 2023-03-22 18:34:18 -07:00
parent 4f3ca23454
commit 42d53b25e5
2 changed files with 47 additions and 17 deletions

View file

@ -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

View file

@ -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)