json.loads() should return a more specific error

Discussion in 'Python' started by Roy Smith, Jun 27, 2012.

  1. Roy Smith

    Roy Smith Guest

    Before I go open an enhancement request, what do people think of the
    idea that json.load() should return something more specific than
    ValueError?

    I've got some code that looks like

    try:
    response = requests.get(url)
    except RequestException as ex:
    logger.exception(ex)
    return []
    data = response.text
    try:
    events = json.loads(data)
    except ValueError as ex:
    logger.error("%s: %r", ex, data)
    return []

    This would be so much neater if json would return something I could
    identify as a json error. It would all just collapse into:

    try:
    events = requests.get(url).json
    except (RequestException, JSONDecodeError) as ex:
    logger.exception(ex)
    return []

    We could make JSONDecodeError a subclass of ValueError so existing code
    would continue to work.
     
    Roy Smith, Jun 27, 2012
    #1
    1. Advertising

  2. Roy Smith

    Terry Reedy Guest

    On 6/27/2012 8:45 AM, Roy Smith wrote:
    > Before I go open an enhancement request, what do people think of the
    > idea that json.load() should return something more specific than
    > ValueError?


    I do not know of any written policy about when to create custom error
    classes in the stdlib. I know there are some that are just empty
    catchall renamings.

    "class ModException(Exception): pass"

    This does not seem to have much use except your use us scanning logs,
    and does have some cost.

    > I've got some code that looks like
    >
    > try:
    > response = requests.get(url)
    > except RequestException as ex:
    > logger.exception(ex)
    > return []
    > data = response.text
    > try:
    > events = json.loads(data)
    > except ValueError as ex:
    > logger.error("%s: %r", ex, data)
    > return []


    You could solve your immediate problem by starting the string with
    something like 'JSON: '. One might want the url included in the log,
    which would never be part of an exception from json. Given that data can
    be arbitrarily long, logging data does not seem like that good an idea.

    To me, the important question is not the exception name, which you can
    replace, but whether the message part of the exception gives information
    about the actual problem. If it just says something redundant and
    useless like 'bad input', then improving that would be a good enhancement.

    > This would be so much neater if json would return something I could
    > identify as a json error. It would all just collapse into:
    >
    > try:
    > events = requests.get(url).json


    Would not this be
    events = json.loads(requests.get(url).text)
    ?
    Either way, 'events' is the only new binding that persists.

    > except (RequestException, JSONDecodeError) as ex:


    Just using ValueError would work if you condition the logging on the
    value of ex.

    > logger.exception(ex)


    This would only be the equivalent of your first code if the arbitrarily
    large input data were attached to the JSONDecodeError -- and thereby
    kept alive when it could otherwise be deleted/collected (and the custom
    class had its own __str__ method). I do not think this a good idea. The
    exception should only contain extracted bits that show the problem.

    > return []
    >
    > We could make JSONDecodeError a subclass of ValueError so existing code
    > would continue to work.


    Bottom line: I do not think you should expect exception instances to
    necessarily have all the info you would want logged for reading out of
    context (as opposed to reading interactively). On the other hand,
    exceptions should contain specific information about the problem that
    the raising code knows and that is hard to get otherwise.

    --
    Terry Jan Reedy
     
    Terry Reedy, Jun 27, 2012
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. gert
    Replies:
    20
    Views:
    4,228
    Richard Brodie
    Jan 27, 2009
  2. Florian Frank
    Replies:
    0
    Views:
    264
    Florian Frank
    Jun 30, 2009
  3. sajuptpm
    Replies:
    2
    Views:
    403
    sajuptpm
    Dec 28, 2012
  4. Acácio Centeno
    Replies:
    1
    Views:
    311
    dieter
    Feb 15, 2013
  5. Bryan Britten
    Replies:
    9
    Views:
    295
    Bryan Britten
    May 28, 2013
Loading...

Share This Page