The error codes (and error messages) come from the server and can be retrieved from an instance of FtpException
when it's Status
is ProtocolError
:
try
{
ftp.GetFile(remotePath, localPath);
}
catch (FtpException error)
{
if (error.Status == FtpExceptionStatus.ProtocolError)
{
int errorCode = error.Response.Code;
// ...
}
throw;
}
Exception codes that indicate the action can be retried should always start with '4', which means this particular FTP server got it wrong. '5' indicates that the action should not be retried...
The exception codes are a subset of FTP reply codes, which are defined by RFC 959. Reply codes are always a three-digit number and error codes always begin with '4' of '5'. However, although the RFC lists some mandatory error codes FTP servers should use for common errors, in practice they often define and use their own error codes. Still, they should at least follow the rules set by the RFC:
4yz Transient Negative Completion reply
The command was not accepted and the requested action did
not take place, but the error condition is temporary and
the action may be requested again. The user should
return to the beginning of the command sequence, if any.
It is difficult to assign a meaning to "transient",
particularly when two distinct sites (Server- and
User-processes) have to agree on the interpretation.
Each reply in the 4yz category might have a slightly
different time value, but the intent is that the
user-process is encouraged to try again. A rule of thumb
in determining if a reply fits into the 4yz or the 5yz
(Permanent Negative) category is that replies are 4yz if
the commands can be repeated without any change in
command form or in properties of the User or Server
(e.g., the command is spelled the same with the same
arguments used; the user does not change his file access
or user name; the server does not put up a new
implementation.)
5yz Permanent Negative Completion reply
The command was not accepted and the requested action did
not take place. The User-process is discouraged from
repeating the exact request (in the same sequence). Even
some "permanent" error conditions can be corrected, so
the human user may want to direct his User-process to
reinitiate the command sequence by direct action at some
point in the future (e.g., after the spelling has been
changed, or the user has altered his directory status.)
The second digit represents function groupings:
x0z Syntax - These replies refer to syntax errors,
syntactically correct commands that don't fit any
functional category, unimplemented or superfluous
commands.
x1z Information - These are replies to requests for
information, such as status or help.
x2z Connections - Replies referring to the control and
data connections.
x3z Authentication and accounting - Replies for the login
process and accounting procedures.
x4z Unspecified as yet.
x5z File system - These replies indicate the status of the
Server file system vis-a-vis the requested transfer or
other file system action.
The third digit gives a finer gradation of meaning in each of the categories.
Unfortunately, the error code you got from the FTP server ("500 PASV: unable to listen; try again later"
) illustrates that the rules are often ignored in practice. A grouping code 5yz
should represent a "Permanent Negative Completion", but the error message clearly contradicts this by encouraging the client to try again. Which is actually a "Transient Negative Completion" and 4yz
codes must be used for those.
The function grouping is wrong as well. x0z
codes should "refer to syntax errors, syntactically correct commands that don't fit any functional category, unimplemented or superfluous commands", which is obviously not the case here. An x2z
reply code would be more appropriate.
In fact, many FTP servers actually use an error code of 425
in this situation.