[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot e5ba4f6 18/69: Automatically reply with error if
From: |
João Távora |
Subject: |
[elpa] externals/eglot e5ba4f6 18/69: Automatically reply with error if dispatcher doesn't |
Date: |
Fri, 22 Jun 2018 11:54:56 -0400 (EDT) |
branch: externals/eglot
commit e5ba4f64e25940dfab1b214f919b91c9a6836aa0
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Automatically reply with error if dispatcher doesn't
* jrpc.el (jrpc-connect): Improve doc.
(jrpc--process-receive): Overhaul error handling.
(jrpc-reply): Protect against missing ID
(jrpc-error): Signal an error with jrpc-specific info.
(jrpc-message): Protect against funky args.
(jrpc-request): Learn to handle jrpc-specific errors.
---
jrpc.el | 76 ++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 45 insertions(+), 31 deletions(-)
diff --git a/jrpc.el b/jrpc.el
index c974fd9..223a4ce 100644
--- a/jrpc.el
+++ b/jrpc.el
@@ -143,12 +143,15 @@ If nil, don't use a timeout (not recommended)."
(jrpc-error "No current JSON-RPC process")))
(defun jrpc-error (format &rest args)
- "Error out with FORMAT with ARGS."
- (error (apply #'format format args)))
+ "Error out with FORMAT with ARGS.
+If invoked inside a dispatcher function, this function is suitable
+for replying to the remote endpoint with a -32603 error code and
+FORMAT as the message."
+ (signal 'error (format "[jrpc] %s" (apply #'format format args))))
(defun jrpc-message (format &rest args)
"Message out with FORMAT with ARGS."
- (message (concat "[jrpc] " (apply #'format format args))))
+ (message "[jrpc] %s" (concat "[jrpc] %s" (apply #'format format args))))
(defun jrpc-warn (format &rest args)
"Warning message with FORMAT and ARGS."
@@ -266,18 +269,17 @@ passed the moribund process object as a single argument.
DISPATCHER specifies how the server-invoked methods find their
Elisp counterpart. It is a function passed (PROC METHOD ID PARAMS
-as arguments:
-
-PROC is the process object returned by this function.
-
-ID is server identifier for a server request, or nil for a server
-notification. In the case of a server request, DISPATCHER is
-reponsible using ID and `jrpc-reply' (which see) to reply.
-
-METHOD is a symbol.
-
-PARAMS contains the method parameters: an object, array, or other
-type.
+as arguments. PROC is the process object returned by this
+function. ID is the server identifier for a server request, or
+nil for a server notification. METHOD is a symbol. PARAMS
+contains the method parameters as JSON data.
+
+If ID is non-nil, DISPATCHER is expected to reply to the
+request. If it doesn't, or if it signals an error before doing
+so, jrpc.el will automatially reply with an error. If DISPATCHER
+signals an error with alist elements `jrpc-error-message' and
+`jrpc-error-code' in its DATA, the corresponding elements are
+used for the automated error reply.
`jrpc-connect' returns a process object representing the server."
(let* ((proc (jrpc--make-process name contact)))
@@ -430,19 +432,25 @@ is a symbol saying if this is a client or server
originated."
(error (jrpc-warn "Invalid JSONRPC message %s: %s" message
(cdr oops))
nil)))
- (continuations))
+ (continuations)
+ (lisp-err))
(jrpc-log-event proc message 'server)
(when error (setf (jrpc-status proc) `(,error t)))
(cond (method
- (unwind-protect
- (funcall (jrpc--dispatcher proc) proc method id params)
- (unless (or (not id)
- (member id (jrpc--server-request-ids proc)))
- (jrpc-reply
- proc id
- :error (jrpc-obj :code -32603 :message "Internal error")))
- (setf (jrpc--server-request-ids proc)
- (delete id (jrpc--server-request-ids proc)))))
+ (condition-case-unless-debug oops
+ (funcall (jrpc--dispatcher proc) proc (intern method) id params)
+ (error (setq lisp-err oops)))
+ (unless (or (member id (jrpc--server-request-ids proc))
+ (not (or id lisp-err)))
+ (jrpc-reply
+ proc id
+ :error (jrpc-obj
+ :code (or (alist-get 'jrpc-error-code (cdr lisp-err))
+ -32603)
+ :message (or (alist-get 'jrpc-error-message (cdr
lisp-err))
+ "Internal error"))))
+ (setf (jrpc--server-request-ids proc)
+ (delete id (jrpc--server-request-ids proc))))
((setq continuations
(and id (gethash id (jrpc--request-continuations proc))))
(let ((timer (nth 2 continuations)))
@@ -593,12 +601,16 @@ DEFERRED is passed to `jrpc-async-request', which see."
(jrpc-async-request
proc method params
:success-fn (lambda (result) (throw tag `(done ,result)))
- :error-fn (jrpc-lambda (&key code message _data)
- (throw tag `(error ,(format "%s: %s" code message))))
- :timeout-fn (lambda () (throw tag '(error "Timed out")))
+ :error-fn (jrpc-lambda (&key code message data)
+ (throw tag `(error (jrpc-error-code . ,code)
+ (jrpc-error-message . ,message)
+ (jrpc-error-data . ,data))))
+ :timeout-fn (lambda ()
+ (throw tag '(error (jrpc-error-message . "Timed
out"))))
:deferred deferred)
(while t (accept-process-output nil 30)))))
- (when (eq 'error (car retval)) (jrpc-error (cadr retval)))
+ (when (eq 'error (car retval))
+ (signal 'error (cons "[jrpc] jrpc-request failed:" (cdr retval))))
(cadr retval)))
(cl-defun jrpc-notify (proc method params)
@@ -607,10 +619,12 @@ DEFERRED is passed to `jrpc-async-request', which see."
:method method
:params params)))
-(cl-defun jrpc-reply (proc id &key result error)
+(cl-defun jrpc-reply (proc id &key (result nil result-supplied-p) error)
"Reply to PROC's request ID with RESULT or ERROR."
+ (unless id (jrpc-error "Need a non-nil ID"))
+ (unless (xor result-supplied-p error)
+ (jrpc-error "Can't pass both RESULT and ERROR!"))
(push id (jrpc--server-request-ids proc))
- (unless (xor result error) (jrpc-error "Can't pass both RESULT and ERROR!"))
(jrpc--process-send
proc `(:jsonrpc "2.0" :id ,id
,@(when result `(:result ,result))
- [elpa] externals/eglot 5cda0ec 06/69: Fix a ridiculous bug when generating transient projects, (continued)
- [elpa] externals/eglot 5cda0ec 06/69: Fix a ridiculous bug when generating transient projects, João Távora, 2018/06/22
- [elpa] externals/eglot e5120aa 08/69: Add jrpc.el to Makefile, João Távora, 2018/06/22
- [elpa] externals/eglot 07359a2 15/69: Allow null timeouts and set default to 3 seconds, João Távora, 2018/06/22
- [elpa] externals/eglot 67d8335 17/69: jrpc.el should know nothing of mode-line updates, João Távora, 2018/06/22
- [elpa] externals/eglot 0e1a5f0 05/69: jrpc-connect is now passed a generic dispatching function, João Távora, 2018/06/22
- [elpa] externals/eglot 078a1a6 13/69: Add full "Commentary" section to jrpc.el, João Távora, 2018/06/22
- [elpa] externals/eglot 2f1d76d 03/69: Proper server shutdown when jrpc.el is used, João Távora, 2018/06/22
- [elpa] externals/eglot a2aa1ed 19/69: Robustify timer handling for jrpc-async-request, João Távora, 2018/06/22
- [elpa] externals/eglot 7769c07 16/69: Send message, then establish continuations, João Távora, 2018/06/22
- [elpa] externals/eglot 7f2e894 11/69: Merge branch 'master' into jsonrpc-refactor (using good ol' git merge), João Távora, 2018/06/22
- [elpa] externals/eglot e5ba4f6 18/69: Automatically reply with error if dispatcher doesn't,
João Távora <=
- [elpa] externals/eglot 33ae871 09/69: More flexible jrpc.el and improve eglot.el's doc, João Távora, 2018/06/22
- [elpa] externals/eglot 3265c1d 10/69: Simpler callback protocol for JSONRPC parameters and results, João Távora, 2018/06/22
- [elpa] externals/eglot e906d25 14/69: Overhaul JSON and JSRONRPC error handling, João Távora, 2018/06/22
- [elpa] externals/eglot 7cd94b9 12/69: Improve jrpc.el's doc (and change jrpc-request's protocol a tiny bit), João Távora, 2018/06/22
- [elpa] externals/eglot 489182d 24/69: New jsonrpc-error error type, João Távora, 2018/06/22
- [elpa] externals/eglot 5cea412 20/69: Fix typos and phrasing in commentary and docstrings, João Távora, 2018/06/22
- [elpa] externals/eglot c30f0f3 23/69: Get rid of jsonrpc.el customization group and timeout, João Távora, 2018/06/22
- [elpa] externals/eglot 5e8fe4c 26/69: Add jsonrpc-tests.el, João Távora, 2018/06/22
- [elpa] externals/eglot 05ff697 29/69: Document current API breaches a bit, João Távora, 2018/06/22
- [elpa] externals/eglot 258e3b0 07/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22