Opened 6 years ago
Closed 6 years ago
#76 closed defect (invalid)
Error message related to OS
Reported by: | ftputiluser | Owned by: | schwa |
---|---|---|---|
Priority: | major | Milestone: | 3.1 |
Component: | Library | Version: | 3.0 |
Keywords: | error message, original exception, socket | Cc: |
Description (last modified by )
python test.py Traceback (most recent call last): File "test.py", line 4, in <module> with ftputil.FTPHost('195.0.0.1:595', 'User1', 'test1') as host: File "/home/nick/Desktop/ftp_testing_python/ftputil/host.py", line 69, in __init__ self._session = self._make_session() File "/home/nick/Desktop/ftp_testing_python/ftputil/host.py", line 129, in _make_session return factory(*args, **kwargs) File "/home/nick/Desktop/ftp_testing_python/ftputil/error.py", line 133, in __exit__ raise FTPOSError(*exc_value.args) ftputil.error.FTPOSError: -2 Debugging info: ftputil 3.0, Python 2.7.3 (linux2)
The following code worked on a different version of ubuntu
import ftputil # Download some files from the login directory. with ftputil.FTPHost('195.0.0.1:595', 'User1', 'test1') as host: names = host.listdir(host.curdir) for name in names: print(name)
Change History (9)
comment:1 Changed 6 years ago by
Description: | modified (diff) |
---|---|
Status: | new → assigned |
Version: | → 3.0 |
comment:2 Changed 6 years ago by
Hi,
Thanks for the report.
Is "the following code" the one that gives the traceback shown at the start of the description (i. e. test.py
)?
One thing I notice in the code is the use of "195.0.0.1:595" for host and port. ftputil
passes this string as the host to ftplib.FTP
. It will then depend on the ftplib
module in the Python standard library whether it will strip off the part after the colon and use that for the port when connecting. From the Python documentation on `ftplib` it doesn't look like the form "host:port" is allowed. I can imagine that the code that was working on another Ubuntu version actually used only a host without port and hence implicitly the default port.
When I do something similar in the interpreter like in your code (note: no ftputil
involved here), I also get an error code -2:
>>> import ftplib >>> f = ftplib.FTP("ftp.gnome.org:21", "anonymous", "") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/ftplib.py", line 117, in __init__ self.connect(host) File "/usr/lib64/python2.7/ftplib.py", line 132, in connect self.sock = socket.create_connection((self.host, self.port), self.timeout) File "/usr/lib64/python2.7/socket.py", line 553, in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): socket.gaierror: [Errno -2] Name or service not known
If you actually want to connect to a non-default port, I recommend you read this section in the ftputil documentation.
comment:3 Changed 6 years ago by
Summary: | error message related to OS → Error message related to OS |
---|
comment:4 follow-up: 5 Changed 6 years ago by
Things to find out and probably use to improve ftputil:
Why does ftputil convert the socket.gaierror
to an FTPOSError
?
This code in ftputil.error.FtplibErrorToFTPOSError.__exit__
is responsible for the conversion:
elif isinstance(exc_value, ftplib.all_errors): raise FTPOSError(*exc_value.args)
In the interpreter:
In [9]: try: ...: f = ftplib.FTP("ftp.gnome.org:21", "", "") ...: except Exception, exc: ...: socket_exc = exc ...: In [11]: isinstance(socket_exc, ftplib.all_errors) Out[11]: True In [13]: ftplib.all_errors Out[13]: (ftplib.Error, IOError, EOFError, ssl.SSLError) In [14]: for exc in ftplib.all_errors: ....: if isinstance(socket_exc, exc): ....: print exc ....: <type 'exceptions.IOError'> In [17]: socket_exc.__class__.mro() Out[17]: [socket.gaierror, socket.error, IOError, EnvironmentError, StandardError, Exception, BaseException, object]
So socket.gaierror
has IOError
in its baseclasses and IOError
is also in the ftplib.all_errors
tuple.
Why is the error message from ftputil only "-2"?
In [18]: socket_exc.args Out[18]: (-2, 'Name or service not known')
ftputil tries to be helpful and shows the error message from the original exception. However, ftputil uses only args[0]
as source of the error message because, as far as I know, there's no guarantee or even a common idiom that args[1:]
contains anything that should be part of an error message.
I still may use heuristics like:
- If the exception inherits from
socket.error
, assumeargs[1]
is the actual message and combineargs[:2]
. (The error code might be useful in some cases. Don't set the ftputil exception'serrno
toargs[0]
though because this might violate callers' expectations.)
- If
args[0]
is an integer, assume thatargs[1]
is the actual message and combine them.
comment:5 Changed 6 years ago by
Replying to schwa:
Why is the error message from ftputil only "-2"?
In [18]: socket_exc.args Out[18]: (-2, 'Name or service not known')ftputil tries to be helpful and shows the error message from the original exception. However, ftputil uses only
args[0]
as source of the error message because, as far as I know, there's no guarantee or even a common idiom thatargs[1:]
contains anything that should be part of an error message.
Why does the message from FTPOSError
only contain the "-2" part even though the exception is constructed with FTPOSError(*exc_value.args)
(see above)?
This is the responsible code from ftputil.error
:
class FTPError(Exception): """General ftputil error class.""" def __init__(self, *args): super(FTPError, self).__init__(*args) # Don't use `args[0]` directly because `args` may be empty. if args: self.strerror = self.args[0] else: self.strerror = "" try: self.errno = int(self.strerror[:3]) except (TypeError, IndexError, ValueError): self.errno = None self.file_name = None def __str__(self): return "{0}\nDebugging info: {1}".format(self.strerror, ftputil.version.version_info)
So by default, ftputil uses only args[0]
for the FTPOSError.strerror
attribute.
comment:6 Changed 6 years ago by
I checked in [6e82349a3a14] to include the full string representation of a previously raised exception. So if you use the "host:port" form now, you get a slightly more informative error message:
>>> host = ftputil.FTPHost("ftp.gnome.org:21", "", "") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "ftputil/host.py", line 69, in __init__ self._session = self._make_session() File "ftputil/host.py", line 129, in _make_session return factory(*args, **kwargs) File "ftputil/error.py", line 139, in __exit__ raise FTPOSError(*exc_value.args, original_exception=exc_value) ftputil.error.FTPOSError: [Errno -2] Name or service not known Debugging info: ftputil 3.0, Python 2.7.5 (linux2)
comment:7 Changed 6 years ago by
Keywords: | error message original exception socket added |
---|---|
Milestone: | → 3.1 |
Resolution: | → fixed |
Status: | assigned → closed |
comment:8 Changed 6 years ago by
Description: | modified (diff) |
---|---|
Resolution: | fixed |
Status: | closed → reopened |
comment:9 Changed 6 years ago by
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
I change the resolution to "invalid" since in my opinion the "lacking" support for the "host:port" syntax is no defect.
The "fixed" referred to the improvement in the error message.
Added code markup to ticket description.