Function: jsonrpc-request

jsonrpc-request is a byte-compiled function defined in jsonrpc.el.gz.

Signature

(jsonrpc-request CONNECTION METHOD PARAMS &key DEFERRED TIMEOUT CANCEL-ON-INPUT CANCEL-ON-INPUT-RETVAL)

Documentation

Make a request to CONNECTION, wait for a reply.

Like jsonrpc-async-request for CONNECTION, METHOD and PARAMS, but synchronous.

Except in the case of a non-nil CANCEL-ON-INPUT (explained below), this function doesn't exit until anything interesting happens (success reply, error reply, or timeout). Furthermore, it only exits locally (returning the JSONRPC result object) if the request is successful, otherwise it exits non-locally with an error of type jsonrpc-error.

DEFERRED and TIMEOUT as in jsonrpc-async-request, which see.

If CANCEL-ON-INPUT is non-nil and the user inputs something while the function is waiting, then it exits immediately, returning CANCEL-ON-INPUT-RETVAL. Any future replies (normal or error) are ignored.

View in manual

Source Code

;; Defined in /usr/src/emacs/lisp/jsonrpc.el.gz
(cl-defun jsonrpc-request (connection
                           method params &key
                           deferred timeout
                           cancel-on-input
                           cancel-on-input-retval)
  "Make a request to CONNECTION, wait for a reply.
Like `jsonrpc-async-request' for CONNECTION, METHOD and PARAMS,
but synchronous.

Except in the case of a non-nil CANCEL-ON-INPUT (explained
below), this function doesn't exit until anything interesting
happens (success reply, error reply, or timeout).  Furthermore,
it only exits locally (returning the JSONRPC result object) if
the request is successful, otherwise it exits non-locally with an
error of type `jsonrpc-error'.

DEFERRED and TIMEOUT as in `jsonrpc-async-request', which see.

If CANCEL-ON-INPUT is non-nil and the user inputs something while
the function is waiting, then it exits immediately, returning
CANCEL-ON-INPUT-RETVAL.  Any future replies (normal or error) are
ignored."
  (let* ((tag (cl-gensym "jsonrpc-request-catch-tag")) id-and-timer
         canceled
         (throw-on-input nil)
         (retval
          (unwind-protect
              (catch tag
                (setq
                 id-and-timer
                 (apply
                  #'jsonrpc--async-request-1
                  connection method params
                  :sync-request t
                  :success-fn (lambda (result)
                                (unless canceled
                                  (throw tag `(done ,result))))
                  :error-fn
                  (jsonrpc-lambda
                      (&key code message data)
                    (unless canceled
                      (throw tag `(error (jsonrpc-error-code . ,code)
                                         (jsonrpc-error-message . ,message)
                                         (jsonrpc-error-data . ,data)))))
                  :timeout-fn
                  (lambda ()
                    (unless canceled
                      (throw tag '(error (jsonrpc-error-message . "Timed out")))))
                  `(,@(when deferred `(:deferred ,deferred))
                    ,@(when timeout  `(:timeout  ,timeout)))))
                (cond (cancel-on-input
                       (unwind-protect
                           (let ((inhibit-quit t)) (while (sit-for 30)))
                         (setq canceled t))
                       `(canceled ,cancel-on-input-retval))
                      (t (while t (accept-process-output nil 30)))))
            ;; In normal operation, continuations for error/success is
            ;; handled by `jsonrpc--continue'.  Timeouts also remove
            ;; the continuation...
            (pcase-let* ((`(,id ,_) id-and-timer))
              ;; ...but we still have to guard against exist explicit
              ;; user-quit (C-g) or the `cancel-on-input' case, so
              ;; discard the continuation.
              (jsonrpc--remove connection id (list deferred (current-buffer)))
              ;; ...finally, whatever may have happened to this sync
              ;; request, it might have been holding up any outer
              ;; "anxious" continuations.  The following ensures we
              ;; call them.
              (jsonrpc--continue connection id)))))
    (when (eq 'error (car retval))
      (signal 'jsonrpc-error
              (cons
               (format "request id=%s failed:" (car id-and-timer))
               (cdr retval))))
    (cadr retval)))