GNU bug report logs - #64919
28.2; jsonrpc.el: jsonrpc-lambda failed to deal with single value

Previous Next

Package: emacs;

Reported by: Yue Yi <includeyy123 <at> gmail.com>

Date: Fri, 28 Jul 2023 17:27:02 UTC

Severity: normal

Found in version 28.2

Done: João Távora <joaotavora <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Yue Yi <includeyy123 <at> gmail.com>
Subject: bug#64919: closed (Re: bug#64919: 28.2; jsonrpc.el:
 jsonrpc-lambda failed to deal with single value)
Date: Sat, 29 Jul 2023 10:12:02 +0000
[Message part 1 (text/plain, inline)]
Your bug report

#64919: 28.2; jsonrpc.el: jsonrpc-lambda failed to deal with single value

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to 64919 <at> debbugs.gnu.org.

-- 
64919: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64919
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: João Távora <joaotavora <at> gmail.com>
To: Yue Yi <includeyy123 <at> gmail.com>
Cc: 64919-done <at> debbugs.gnu.org
Subject: Re: bug#64919: 28.2; jsonrpc.el: jsonrpc-lambda failed to deal with
 single value
Date: Sat, 29 Jul 2023 11:14:17 +0100
Hello Yue Yi,

Yue Yi <includeyy123 <at> gmail.com> writes:

> Currently I'm trying to write an toturial about using JSON-RPC in
> Emacs, so I spent some time to read the source code and document and
> found #bug64888.

That's a great idea.  Have you looked at the jsonrpc.el test application
in test/lisp/jsonrpc-tests.el?  It has a simple application, but it's
not very well commented, so a well-described tutorial that does a
similar simple application is welcome.

> Here is another bug I find.

Yes, you've found a bug.  I have fixed it in master
3bbe6f4abc6c1dd8f414e48af5b6ce344bce34db.  I have closed this bug, but
we can keep chatting.

But read on because I think you are misunderstanding the library in some
aspects.

> When I do a async request through `jsonrpc-async-request' without
> specifing :success-fn, emacs will signal an error. Here is the code I
> use:

Doing jsonrpc-async-request without success-fn is possible but oesn't
make much sense, becase there's nothing to react to whatever the server
returned for this remote proceedure call if the request succeeds.
  
> --- 
> (defclass yy-rpc (jsonrpc-connection)
>   ((place
>     :initarg :place
>     :accessor yy-place)))
> (cl-defmethod jsonrpc-connection-send ((conn yy-rpc)
>                                  &key id method params result error)
>   (setcar (yy-place conn)
>           (append (if id `(:id ,id))
>                  (if method `(:method ,method))
>                  (if params `(:params ,params))
>                  (if result `(:result ,result))
>                  (if error  `(:error  ,error)))))
> (setq a (cons nil nil))
> (setq b (yy-rpc :name "1" :place a))

By the way, this isn't how you make objects in Common Lisp (or in Emacs
Lisp's emulation of it, which is what we have here).  You would have to
use 'make-instance'

I also don't understand what your code is supposed to perform.  Look at 
the test/lisp/jsonrpc-tests.el to get an idea of how to do these kinds
of servers.

You should first be able to describe in plain English what you want this
tutorial example to showcase.  Do you want to make a simple JSONRPC
client that asks the endpoint to perform elementary arithmetic remotely?
Fine.  Where do you want the remote endpoint to live?  The same Emacs?
Another Emacs?  Another process running a program written in another
language?

Try to first answer these questions and have a very clear idea in your
head of what you want to demonstrate in the tutorial.

As I said, it's a very good idea in principle.  But from your
description of it, it seems still a bit fuzzy.

> (jsonrpc-async-request b "add" [1 2])
> (jsonrpc-connection-receive b '(:result 3 :id 1))

Here is what may be a significant mistake: the
'jsonrpc-connection-receive' is not meant to be called by the
_application_ writer.

Instead it is meant to be called by the _library_ writer, i.e. someone
who is extending 'jsonrpc.el' to a new transport (other than TCP/IP
sockets).

In other words, you're mixing up two ways to use jsonrpc.el.  They are
both described in 33.32.1 JSONRPC Overview

  1. A user interface for building JSONRPC applications
  2. A inheritance interface for building JSONRPC transport
     implementations

Thse are two completely separate use cases.

I _think_ you first want to do 1, to get a feeling of how to use the
library as an application writer.  Only then should you move on to 2 to
understand how to user the library an implementor of new transports.

Only then you'll get to mess with 'jsonrpc-connection-receive', which
you're doing right now.

João

[Message part 3 (message/rfc822, inline)]
From: Yue Yi <includeyy123 <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Cc: João Távora <joaotavora <at> gmail.com>
Subject: 28.2; jsonrpc.el: jsonrpc-lambda failed to deal with single value
Date: Sat, 29 Jul 2023 01:59:09 +0900
[Message part 4 (text/plain, inline)]
Currently I'm trying to write an toturial about using JSON-RPC in
Emacs, so I spent some time to read the source code and document and
found #bug64888.



Here is another bug I find: When I do a async request through
`jsonrpc-async-request' without specifing :success-fn, emacs will
signal an error. Here is the code I use:



---

(defclass yy-rpc (jsonrpc-connection)

  ((place

    :initarg :place

    :accessor yy-place)))

(cl-defmethod jsonrpc-connection-send ((conn yy-rpc)

                                 &key id method params result error)

  (setcar (yy-place conn)

          (append (if id `(:id ,id))

                 (if method `(:method ,method))

                 (if params `(:params ,params))

                 (if result `(:result ,result))

                 (if error  `(:error  ,error)))))

(setq a (cons nil nil))

(setq b (yy-rpc :name "1" :place a))



(jsonrpc-async-request b "add" [1 2])

(jsonrpc-connection-receive b '(:result 3 :id 1))

---



I just make a very simple subclass `yy-rpc' and response to it "by
hand", after evaluating the above code, I get:



---

Debugger entered--Lisp error: (wrong-type-argument listp 3)

---



By reading the code of `jsonrpc--async-request-1', I find the default
:success-fn callback uses the macro jsonrpc-lambda and I know why it
happened:



---

(funcall (jsonrpc-lambda (&rest _ignored) nil) 3)

=> Debugger entered--Lisp error: (wrong-type-argument listp 3)

---



It seems that `jsonrpc-lambda' cannot handle single value. Maybe We
can change its last line from



`(lambda (,e) (apply (cl-function (lambda ,cl-lambda-list ,@body)) ,e))))



to



`(lambda (,e) (apply (cl-function (lambda ,cl-lambda-list ,@body)) ,e ())))



After change it and M-x eval-buffer, I can get the right behavior
using the code above.



Is it the right way?



Regards



YI YUE
[Message part 5 (text/html, inline)]

This bug report was last modified 2 years and 25 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.