Python error codes and messages location

Cameron Simpson cs at zip.com.au
Mon May 27 02:11:54 EDT 2013


On 27May2013 04:49, Carlos Nepomuceno <carlosnepomuceno at outlook.com> wrote:
| > From: steve+comp.lang.python at pearwood.info
| > On Mon, 27 May 2013 02:13:54 +0300, Carlos Nepomuceno wrote:
| >> Where can I find all error codes and messages that Python throws (actual
| >> codes and messages from exceptions raised by stdlib)?
| >
| > There is no list. It is subject to change from version to version,
| > including point releases.
[...]
| > "Read the source code."
[...]
| 
| That's bad! I'd like to check all the IOError codes that may be
| raised by a function/method but the information isn't there.

No, you really don't.

There are particular, expected, errors you know what to do with
and can proceed in the face of.

And there will often be errors you _don't_ know what to do with.
With the latter, what is your program going to do? You often can't
proceed, so all you can do is log the error and cancel, cleaning
up as you back out. In that circumstance, how will knowing the name
of the error help? You've logged it, and hopefully the exception
message is sufficient.

| Take open() for example[1]. It only says it raises an IOError exception.
| 
| I've had to try "open('','r')" to discover that Errno 22 is the one "IOError: [Errno 22] invalid mode ('r') or filename: ''"

It is vague because that is an OS level error, and errno 22 is
EINVAL. For example, MacOSX says (in "man 2 intro"):

     22 EINVAL Invalid argument.  Some invalid argument was supplied. (For
             example, specifying an undefined signal to a signal or kill func‐
             tion).

It happens that above, the filename '' is invalid.

But so what? That call is _never_ going to work because the arguments
are invalid. So you response will be the same, programmatically,
as with many other errors: log and abort.

| Will I only be able to get all error codes reading the source code of open()?

Nope. Well, not directly.

Python open call's the OS' open. If that succeeds, Python does some
more housekeeping and hands you a "file" python object. But if the
OS open fails, Python reports the OS error.

From the Python source you will see that the OS open is called. So
you must then go to the OS docuemntation for further information.

| Is there a way to simulate the errors instead of actually causing
| them? I mean not raising an instance of IOError that I create (like
| "raise IOError(666,'Hell happens')"), but one with the actual
| contents 'args = (errno, strerr)' that open() would raise?
| 
| Something like:
| 
| f=open('filename','r')
| for x in range(25):
|     try:
|         f.raise_errno(x)
|     except IOError, e:
|         if   e.errno == 1:
|             treat_err1()
|             continue
|         elif e.errno == 2:
|             treat_err2()
|             continue

Well, maybe this (untested):

  for x in range(25):
      try:
          exc = OSError(os.strerror(x))
          exc.errno = x
          raise exc
      except IOError, e:
          if   e.errno == 1:
              treat_err1()
              continue
          elif e.errno == 2:
              treat_err2()
              continue

BTW, I recommend importing "errno" and using symbolic names. It makes things much more readable, and accomodates the situation where the symbols map to different numbers on different platforms. And have a catch-all. For example:

  import errno
  ...
  try:
    f = open(filename, .....)
  except OSError, e:
    if e.errno == errno.EPERM:
      ... Operation not permitted ...
    elif e.errno == errno.ENOENT:
      ... No such file or directory ...
    else:
      # surprise!
      # log message, let the exception get out
      # callers can catch things in turn
      logging.error("open(%s) fails: %s" % (filename, e))
      raise

| >> I've already found the module 'errno' and got a dictionary
| >> (errno.errorcode) and some system error messages
| >> (os.strerror(errno.ENAMETOOLONG)) but there's more I couldn't find.
| >
| > These are the standard C operating system and file system error codes,
| > not Python exceptions.
| 
| Yes, the docs say it's from "linux/include/errno.h". 		 	   		  

On Linux, yes. In general, on any UNIX system the command "man 2
intro" lists the errors that system calls like open may return. And
"man 2 open" should list the particular errors that open can return.
_On that platform_.

The platform variation is a major reason why you should not hope
to enumerate all the errors; the other reason is that you can't
treat every error individually in a fine grained fashion without
making your code hard to read and maintain: the core logic of the
program is hidden behind a forest of tiny little special cases.

Your code will be clearer if you handle the errors that are expected
and that permit the program to proceed sensible. Other errors should
elicit a log message of course, but if you can't proceed with the
task at hand you can almost certainly only abort and try to tidy
up while doing so.

Cheers,
-- 

Processes are like potatoes.    - NCR device driver manual



More information about the Python-list mailing list