5

I am sending some jsonrpc requests to a web2py server, with a celery backend. Sometimes, I get errors which I want to analyze. The errors come escaped in the jsonrpc reply, so they are not easy to understand. I get something like this:

{"version": "1.1", "id": "ID4", "error": {"message": "TypeError: 'NoneType' object does not support item assignment", "code": 100, "data": ["  File \"/home/myuser1/tmp/web2py/gluon/tools.py\", line 4068, in serve_jsonrpc\n    s = methods[method](*params)\n", "  File \"/home/myuser1/tmp/web2py/applications/mycompany_portal/controllers/activity.py\", line 66, in get_cdr_page\n    invalidate_cache = pars['invalidate_cache'], use_long_polling = pars['use_long_polling'])\n", "  File \"/home/myuser1/projects/new-mycompany-portal/python_modules/pmq_client.py\", line 85, in get_page\n    res = result.get(timeout=10)\n", "  File \"/home/myuser1/.virtualenvs/python2.7.2-mycompany1/lib/python2.7/site-packages/celery/result.py\", line 119, in get\n    interval=interval)\n", "  File \"/home/myuser1/.virtualenvs/python2.7.2-mycompany1/lib/python2.7/site-packages/celery/backends/amqp.py\", line 138, in wait_for\n    raise self.exception_to_python(meta['result'])\n"], "name": "JSONRPCError"}}

What I want is to get the error.data part of the jsonrpc reply, unescape it and display it as a stacktrace. I can do it manually (change \" -> " and process the \n), but I would like to avoid reinventing the wheel here.

blueFast
  • 41,341
  • 63
  • 198
  • 344
  • If that's the JSON then the string should "not contain those extra quotes" after running it through a JSON deserializer before extracting the value .. –  Dec 27 '12 at 10:42
  • that is the text of the reply, before processing it through the json decoder. – blueFast Dec 27 '12 at 10:43
  • So: `deserilize(json)['error']['message']`? Unless there is a good reason to *not* deserialize it, that would be the way that - in an obvious non-clever way - "avoid[s] reinventing of the wheel". –  Dec 27 '12 at 10:44
  • With the new title it does not look clever, indeed. But before you actually realize that is just a json encoded string, coming up with the json decoder thing *is* clever. My problem was that the reply I get is not always json (I am doing different kinds of requests), so I was not properly decoding the json in case of errors (I am doing it right if there are no errors, though). – blueFast Dec 27 '12 at 10:57
  • Yes, hindsight is 20/20 :) –  Dec 27 '12 at 10:59

2 Answers2

3

Is this raw unparsed JSON? Parse it as JSON:

import json
print ''.join(json.loads(yourstring)['error']['data'])
Pavel Anossov
  • 60,842
  • 14
  • 151
  • 124
  • 1
    +1 Without further constraints, I'd first deserialize the JSON. (The JSON library already handles all the "tricky" rules.) –  Dec 27 '12 at 10:48
0

Re-edit:

Use:

unquote

http://docs.python.org/2/library/urllib.html#urllib.unquote

or

unquote_plus

http://docs.python.org/2/library/urllib.html#urllib.unquote_plus

for unescape-ing HTTP-like data (ie. percentage-escaping)

See this question and answers for more info:

Unescape Python Strings From HTTP

And, for unescape-ing regular escaped symbols (ie. backslashes), use .decode() (counterpart of .encode()). See these answers:

https://stackoverflow.com/a/10944959/1284631

https://stackoverflow.com/a/9340191/1284631

Community
  • 1
  • 1
user1284631
  • 4,446
  • 36
  • 61