3

I am completely noob at handling exceptions and I've been learning to work with IMDbPy. I wanted to catch the exception if a user enters an invalid ID. I tried

import imdb
from imdb import IMDbDataAccessError
ia = imdb.IMDb(accessSystem='http')
try:
    movie = ia.get_movie('12121212212121')
except IMDbDataAccessError:
    print("error")

But it doesn't print the text "error" rather it shows the error message. Which is -

IMDbDataAccessError exception raised; args: ({'errcode': None,
'errmsg': 'None', 'url':
'https://www.imdb.com/title/tt12121212212121/reference', 'proxy': '',
'exception type': 'IOError', 'original exception': <HTTPError 404:
'Not Found'>},); kwds: {}
lucidbrot
  • 5,378
  • 3
  • 39
  • 68
tahnoon
  • 133
  • 1
  • 14

2 Answers2

5
import imdb
from imdb import IMDbDataAccessError
try:
    ia = imdb.IMDb(accessSystem='http', reraiseExceptions=True)
    movie = ia.get_movie('12121212212121')
except:
    print("error")

The option to reraiseExceptions helps. Now the program outputs the trace AND afterwards error. Note that since May 2021 reraiseExceptions=True should already be the default.


I found this by looking at the source of the functions that raised the Exception. i.e. retrieve_unicode and update. Searching for "ret = method(mopID)" I found this which only raises the exception again if self._reraise_exceptions is set to true in the IMDB Base object.

I created an issue asking them to please make it more obvious that this setting is necessary. The creator replied:

I think it would be better to just always raise the exception.
I'll consider the change for a future release.


Also worth noting is this excerpt of their config:

## Set the threshold for logging messages.
# Can be one of "debug", "info", "warning", "error", "critical" (default:
# "warning").
#loggingLevel = debug

which implies that you can reduce the verbosity of the logs. However, passing a loggingLevel="critical" parameter does not seem to reduce the console output. That is because these errors are themselves of the level critical.
However, you can disable the logger completely:

import imdb
from imdb import IMDbDataAccessError
import logging
try:
    logger = logging.getLogger('imdbpy');
    logger.disabled = True
    ia = imdb.IMDb(accessSystem='http', reraiseExceptions=True, loggingLevel="critical")
    movie = ia.get_movie('12121212212121')
except IMDbDataAccessError:
    print("error")

The names of the loggers are currently 'imdbpy' and 'imdbpy.aux'.


update May 2021

There has been some activity on the github issue:

Just committed a change to the default behavior: now if not specified reraiseExceptions is True.

This means that any exception is re-raised.

If this breaks something important let us know, but I think this should be better handled catching the exception in the caller code.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68
  • 1
    Thank you for taking the time to check into it and explain. But it still shows me the error messages instead of just printing "error". It does print "error" in the end though. Also I forgot to mention that the code also raises HTTPError 404 which I tried catching but no luck. Can you help? – tahnoon Sep 27 '19 at 09:05
  • 1
    The error messages that it shows are likely from some form of logging. They happen, are logged, caught, raise a new exception because of the previous one, get logged, caught and so on until you finally catch it and print "error". So they should not be bothering you in terms of functionality. Of course, they clutter the output, so perhaps there is an option to silence this in the library. I do not know (yet) – lucidbrot Sep 27 '19 at 13:43
  • @tahnoon Please see my edit. And consider accepting the answer if this fits your needs :) – lucidbrot Sep 27 '19 at 13:59
  • That worked like a charm. Thank you, I really appreciate your help. :D – tahnoon Sep 27 '19 at 15:01
  • Thanks for your appreciative words :) Happy I could help – lucidbrot Sep 28 '19 at 05:04
0

The raised exception is of type IOError, which is one of the Python built-in exceptions and you're only catching IMDbDataAccessError which is not a parent of IOError.

You can catch them separately (example with ZeroDivisionError instead of IOError), like:

try:
    1/0
except IMDbDataAccessError:
    print("problem in IMDbPY")
except ZeroDivisionError:
    print("division by zero error")

or just catch anything; beware that this is considered a bad practice since it can mask other problems and make your code difficult to debug, but in some cases it makes sense:

try:
    1/0
except Exception as e:
    print("ERROR: %s" % e)
Davide Alberani
  • 1,061
  • 1
  • 18
  • 28