aboutsummaryrefslogtreecommitdiff
path: root/doc/bugs/Error_with_external_plugins.mdwn
blob: 065439de8c29272699e739a2be8cc41b995ffc30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Hello,
I stumbled upon this bug when writing a Python plugin. I think this is a ikiwiki bug, since I do not think my plugin does anything wrong.

# Example

I set up an example wiki, containing the setup file and the plugin, [[on github|https://github.com/paternal/ikiwiki-rpcbug]].

1. Clone the repository

        git clone https://github.com/paternal/ikiwiki-rpcbug.git

2. Change to the right directory

        cd ikiwiki-rpcbug

2. Add the right ikiwiki directory to PYTHONPATH

        export PYTHONPATH="$PYTHONPATH:$(dirname $(dpkg -L ikiwiki | grep proxy))"

3. Build the wiki

        ikiwiki --setup wiki.setup --rebuild

4. The problem is in page [[http://localhost/~USERNAME/ikiwiki_bug_rpc/foo/]] (for instance, [[http://localhost/~USERNAME/ikiwiki_bug_rpc]] is fine.

# Problem

Page `foo` contains the directive ``[[!rpcbug]]`` (`rpcbug` being the name of the plugin). Calling [[``proxy.rpc("srcfile", "bar")``|https://github.com/paternal/ikiwiki-rpcbug/blob/master/plugins/rpcbug#L15]] in the preprocess function seems to mess up the RPC communication between ikiwiki and the plugin, and the result is that the generate `foo/index.html` page is a text file containing the return value of the `preprocess` call.

What I do not understand is that disabling the `format` function (by commenting [[line 46 of the plugin|https://github.com/paternal/ikiwiki-rpcbug/blob/master/plugins/rpcbug#L46]]) solves the problem. Half of an explaination is that I think that when the the ``proxy.rpc`` function is called, the RPC communication is messed up in such a way that the `format` function is not called, and the return value of `preprocess` is considered to be the whole html code of the resulting page.

> I understood that: as the first rpc call messes up the communication, more rpc calls are messed up, but if there is only one rpc call, not that much is broken. -- [[Louis|spalax]]

I hope someone will understand the problem better than I do, because I have no idea about how to solve this.

Regards,    
-- [[Louis|spalax]]

> I used the debug feature provided with `proxy.py` and rebuilt the wiki. I ran this with [this version](https://github.com/paternal/ikiwiki-rpcbug/tree/b4ba34a8edd1b97989965af69eddac050bc0a8ba) of my minimal bug example.
> 
> * The bug happens in function [preprocess](https://github.com/paternal/ikiwiki-rpcbug/blob/b4ba34a8edd1b97989965af69eddac050bc0a8ba/plugins/rpcbug#L12-17) (in call to [srcfile](https://github.com/paternal/ikiwiki-rpcbug/blob/b4ba34a8edd1b97989965af69eddac050bc0a8ba/plugins/rpcbug#L15), to be more precise).
> * The directive causing the bug is called on page [foo](https://github.com/paternal/ikiwiki-rpcbug/blob/b4ba34a8edd1b97989965af69eddac050bc0a8ba/foo.mdwn).
> * Communication between Ikiwiki and the plugin is [[here|debug]].
> * The resulting HTML (for page `foo`) looks like:
> 
> > \[[!rpcbug Erreur: internal error: foo cannot be found in /home/louis/projets/ikiwiki/rpcbug or underlay]]
> >
> >
> > Calling srcfile(foo): page    
> > Calling srcfile(README.md): /home/louis/projets/ikiwiki/rpcbug/README.md
> 
> My analysis:
> 
> * The call to `srcfile(foo)` fails (because Ikiwiki thinks that page `foo` does not exist).
> * Ikiwiki thinks that processing of the directive is finished, whereas the plugin still waits for the answer of Ikiwiki.
> * Ikiwiki asks the plugin to render a new directive, but the plugin interprets the request as the return value for its previous request. Thus, the plugin thinks that `srcfile(foo)` is `page` (this `page` being a misinterpretation of the Ikiwiki request).
> 
> So, I think that this might be an error in the
> [`rpc_call`](https://github.com/joeyh/ikiwiki/blob/9476e2ac7ad2f53643fa2fca6ba35fcc55ab058e/IkiWiki/Plugin/external.pm#L46-147)
> function of the `external` plugin: when the called method fails, it should
> return something (or raise an exception, if this is possible in RPC) to notify
> the plugin that something went wrong.
> 
> -- [[Louis|spalax]]

>> Update: This can actually be a [proxy](https://github.com/joeyh/ikiwiki/blob/9c910a76e70111c50ba8cbb518277f809fc1d09d/plugins/proxy.py) error. Indeed:
>> 
>> - Ikiwiki sends a `methodCall` message to the plugin (which is a call to the
>>   `preprocess` function);
>> - the plugin sends a `methodCall` message to ikiwiki (which is a call to the
>>   `srcfile` function);
>> - Ikiwiki answers with a `methodCall` message:
>>   - Ikiwiki answers this because the function call failed, and it is already
>>     processing the next directive;
>>   - the plugin thinks that it is its request answer, and misinterprets it.
>> 
>> Thus, I think that the bug is in the `proxy.py` python file. On receiving a
>> `methodCall` (instead of a `methodResponse`) as an answer to a `methodCall`
>> request, `proxy.py` should notice the type of request, and call the requested function.
>> 
>> I know Python better than I know Perl, so I can try to fix this.
>> 
>> -- [[Louis|spalax]]

>>> [[!template id=gitbranch author="[[Louis|spalax]]" branch=spalax/paternal/rpcbug
>>>   browse=https://github.com/paternal/ikiwiki/tree/paternal/rpcbug]]
>>> [I fixed this bug](https://github.com/paternal/ikiwiki/commit/32da347566a7559ca1ef145880efe961dbcc012f) in a branch on my Ikiwiki clone.
>>> Please review :)
>>> 
>>> -- [[Louis|spalax]]