Issue1742770

classification
Title: urllib.urlopen('http://inv') -> UnknownHostException in RC 1
Type: Severity: normal
Components: None Versions:
Milestone:
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: amak Nosy List: amak, pekka.klarck
Priority: normal Keywords:

Created on 2007-06-25.11:02:49 by pekka.klarck, last changed 2007-07-01.19:15:46 by amak.

Messages
msg1651 (view) Author: Pekka Klärck (pekka.klarck) Date: 2007-06-25.11:02:49
Noticed a message at jython.org that RC 1 is out (great stuff!!) and immediately run our projects acceptance tests against it. Noticed only one small regression when trying to use urllib.urlopen to access something on a non-existing host. There used to be an IOError but now you get a java.net.UnknownHostException (which goes through if you are excepting IOError or any Python based exception). Details about this on Jython 2.2b1 and RC1 as well as on Python 2.5 are below.

Note that doing urllib.urlopen('nonexisting') causes an IOError also on RC1 i.e. the problem appears only when you specify the protocol. 

Based on the stacktrace this seems to be somehow related to new socket/select implementation (which I hardly can wait to test with telnetlib). If so, the same problem can appear also in other places when trying to open non-existing/not-available network resources.


Jython 2.2rc1 on java1.5.0_11
Type "copyright", "credits" or "license" for more information.
>>> import urllib
>>> urllib.urlopen('http://nonexisting')
Traceback (innermost last):
  File "<console>", line 1, in ?
  File "C:\jython2.2rc1\Lib\urllib.py", line 73, in urlopen
  File "C:\jython2.2rc1\Lib\urllib.py", line 178, in open
  File "C:\jython2.2rc1\Lib\urllib.py", line 292, in open_http
  File "C:\jython2.2rc1\Lib\httplib.py", line 699, in endheaders
  File "C:\jython2.2rc1\Lib\httplib.py", line 585, in _send_output
  File "C:\jython2.2rc1\Lib\httplib.py", line 552, in send
  File "C:\jython2.2rc1\Lib\httplib.py", line 519, in connect
  File "C:\jython2.2rc1\Lib\socket.py", line 319, in getaddrinfo
  File "C:\jython2.2rc1\Lib\socket.py", line 290, in gethostbyname
        at java.net.InetAddress.getAllByName0(Unknown Source)
        at java.net.InetAddress.getAllByName0(Unknown Source)
        at java.net.InetAddress.getAllByName(Unknown Source)
        at java.net.InetAddress.getByName(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)

java.net.UnknownHostException: java.net.UnknownHostException: nonexisting: nonex
isting
>>>


Jython 2.2b1 on java1.5.0_10 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>> import urllib
>>> urllib.urlopen('http://nonexisting')
Traceback (innermost last):
  File "<console>", line 1, in ?
  File "C:\jython2.2b1\Lib\urllib.py", line 73, in urlopen
  File "C:\jython2.2b1\Lib\urllib.py", line 178, in open
  File "C:\jython2.2b1\Lib\urllib.py", line 292, in open_http
  File "C:\jython2.2b1\Lib\httplib.py", line 699, in endheaders
  File "C:\jython2.2b1\Lib\httplib.py", line 585, in _send_output
  File "C:\jython2.2b1\Lib\httplib.py", line 552, in send
  File "C:\jython2.2b1\Lib\httplib.py", line 519, in connect
  File "C:\jython2.2b1\Lib\socket.py", line 83, in getaddrinfo
  File "C:\jython2.2b1\Lib\socket.py", line 67, in gethostbyname
IOError: [Errno socket error] java.net.UnknownHostException: nonexisting: nonexi
sting
>>>


Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on wi
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib
>>> urllib.urlopen('http://nonexisting')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\Python25\lib\urllib.py", line 82, in urlopen
    return opener.open(url)
  File "c:\Python25\lib\urllib.py", line 190, in open
    return getattr(self, name)(url)
  File "c:\Python25\lib\urllib.py", line 325, in open_http
    h.endheaders()
  File "c:\Python25\lib\httplib.py", line 856, in endheaders
    self._send_output()
  File "c:\Python25\lib\httplib.py", line 728, in _send_output
    self.send(msg)
  File "c:\Python25\lib\httplib.py", line 695, in send
    self.connect()
  File "c:\Python25\lib\httplib.py", line 663, in connect
    socket.SOCK_STREAM):
IOError: [Errno socket error] (11001, 'getaddrinfo failed')
>>>
msg1652 (view) Author: Alan Kennedy (amak) Date: 2007-06-26.18:58:49
I see the problem, thanks for reporting it.

It is in the new socket module, caused by a missing entry in the java->cpython exception map.

It is easy to fix, at least in terms of exception mapping. I have fixed the code to produce the correct pythonic exception in this circumstance.

However, I can't find the symbolic constant that represents the errno for the exception.

The error number given above in the cpython log shows an errno of 11001. I get the same error number when I run the code on windows cpython 2.5.

But there is no SYMBOLIC_CONSTANT in the errno module that corresponds to errno 11001?

Do you know what the correct errno symbolic constant is for that cpython (11001, "getaddrinfo failed") exception?
msg1653 (view) Author: Alan Kennedy (amak) Date: 2007-06-26.19:03:45
[OP]
> Note that doing urllib.urlopen('nonexisting') causes an IOError also on RC1
> i.e. the problem appears only when you specify the protocol.

That observation is correct; the problem only appears when you specify a socket-based protocol to urllib.urlopen, e.g. http, ftp, etc.

Urllib.urlopen defaults to the file: protocol if you don't specify one, and so tries to open a local file called "nonexisting", and correctly fails with 

IOError: [Errno 0] No such file or directory: nonexisting

In this circumstance, there is no attempt to create a socket, so the mismapped exception does not occur.
msg1654 (view) Author: Pekka Klärck (pekka.klarck) Date: 2007-06-27.12:32:25
Great that the exception is fixed. I have no idea where to get errnos. To be honest I've never used them in my scripts/programs as just catching and reporting the exception has been enough.
msg1655 (view) Author: Alan Kennedy (amak) Date: 2007-07-01.19:15:46
OK, I've checked in a fix, which will be in 2.2rc2.

When you try to look up and non-existent host, you will get a pythonic exception. The error number corresponds to a newly created symbolic constant.

Jython 2.2rc1 on java1.4.2_13
Type "copyright", "credits" or "license" for more information.
>>> import urllib
>>> urllib.urlopen("http://nonexistent")
Traceback (innermost last):
  File "<console>", line 1, in ?
  File "c:\jython_trunk\jython\dist\Lib\urllib.py", line 73, in urlopen
  File "c:\jython_trunk\jython\dist\Lib\urllib.py", line 178, in open
  File "c:\jython_trunk\jython\dist\Lib\urllib.py", line 292, in open_http
  File "c:\jython_trunk\jython\dist\Lib\httplib.py", line 699, in endheaders
  File "c:\jython_trunk\jython\dist\Lib\httplib.py", line 585, in _send_output
  File "c:\jython_trunk\jython\dist\Lib\httplib.py", line 552, in send
  File "c:\jython_trunk\jython\dist\Lib\httplib.py", line 519, in connect
  File "c:\jython_trunk\jython\dist\Lib\socket.py", line 323, in getaddrinfo
  File "c:\jython_trunk\jython\dist\Lib\socket.py", line 294, in gethostbyname
IOError: [Errno socket error] (20001, 'getaddrinfo failed')
>>> import errno
>>> errno.errorcode[20001]
'EGETADDRINFOFAILED'
>>>
History
Date User Action Args
2007-06-25 11:02:49pekka.klarckcreate