有关此错误的一点背景:客户在其日志文件中获取此错误消息并且支持尚未能够重现它。所以我正在审查代码,试图确定可能发生的事情。我通过查看他们的日志文件将其缩小到代码的这一部分。我没有写这段代码,但它的目的是将一个zip文件ftp到远程服务器。所以问题是......
这段代码可能会抛出“索引超出数组范围”的异常?
FtpLib.FTPFactory ff = new FtpLib.FTPFactory();
try
{
ff.setRemoteHost(job.FTPHost);
ff.setRemoteUser(job.FTPUser);
ff.setRemotePass(job.FTPPW);
ff.login();
// Execute misc. extra commands
foreach (string command in job.Commands)
{
if (log.IsDebugEnabled)
log.Debug("JOB: " + job.ID + " -- FTP Command \"" + command + "\" sent...");
ff.sendCommand(command);
if (log.IsDebugEnabled)
log.Debug("JOB: " + job.ID + " -- Response: " + ff.getLastMessage());
}
try
{
ff.mkdir(job.FTPRemoteDir);
}
catch (IOException) { }
ff.chdir(job.FTPRemoteDir);
ff.setBinaryMode(true);
if (log.IsInfoEnabled)
log.Info("JOB: " + job.ID + " -- FTP UPLOAD: \"" + zipfile.Name + "\" to \"" + job.FTPHost + "/" + job.FTPRemoteDir + "/\"");
ff.upload(zipfile.FullName);
if (log.IsInfoEnabled)
log.Info("JOB: " + job.ID + " -- Completed.");
bFTPSuccess = true;
break;
}
提前致谢!
更新: 我想我们都非常同意这个问题将出现在FTPLib中,我会看看我们是否有源代码。我发现这是一个模糊的错误,客户甚至无法一致地重现,所以这将是一个有趣的一针点。我使用Exception.StackTrace和Exception.ToString函数添加了额外的调试日志记录。一旦问题解决了,我会再次更新并尝试用正确答案给予正确的人,尽管每个人都提出了很好的建议。谢谢你的帮助!
答案 0 :(得分:2)
不知道其他代码可能很难分辨。对我而言最突出的是:
ff.getLastMessage()
但这只是一个有根据的猜测(例如,如果消息存储在数组或simliar中,以及最后的摘录)
答案 1 :(得分:2)
我建议您在当前捕获越界异常的位置记录Exception.StackTrace。 Exception.ToString()也非常有用,因为它提供了大部分重要信息。这应该告诉你抛出异常的确切位置(无需猜测)。但要注意捕获异常并隐藏它的代码 - 我看到你发布的代码有“catch(IOException){}”。还要警惕捕获异常的代码,然后抛出一个不同的异常,这将掩盖原始错误。
只要在调用链中的某个点捕获并记录任何异常,就不应该需要包含try ... catch单个可疑行 -
答案 2 :(得分:1)
我不认为这是任何一行代码。
我的第一个猜测是你的 foreach 循环中的内容,但这看起来非常可靠。
你确定这是代码的一部分吗?
可以粘贴堆栈跟踪吗?
答案 3 :(得分:1)
ff.getLastMessage()
这种方法有什么作用?它是如何得到最后一条消息的?如果它使用messages[messages.Count - 1]
或类似的东西,并且消息集合为空,则会抛出该错误。那是我最好的猜测。
答案 4 :(得分:1)
没什么明显的。它将归结为FtpFactory(我的可能原因投票)和日志的实际实现。
如果创建这些类型的代价很高,工厂可能会保留它创建的类型的实例数组。因此,当您第一次执行可能需要使用其中一个实例(“ff.login”)的操作时,可能会暴露该错误。
我建议你将任何使用try / catch工厂的尝试包围起来,并在日志中记录它。另外,我建议不要使用那个工厂,因为它是由一个很少考虑标准和做法的人写的(小写方法名称?),这是工艺不佳的警示标志。
tl;博士:不要相信你的ftp工厂。它可能很糟糕。
答案 5 :(得分:1)
除了Will的帖子之外,为了完整性:
FtpLib.FTPFactory ff = null; try { ff = new FtpLib.FTPFactory(); } catch(Exception ex) { // Log it }
另外,我不禁想知道,登录是否有效,这是另一个在try / catch块中包装它的地方
try { ff.login(); } catch(Exception ex) { // Log it. }
可能是登录失败了,ff
正用于执行命令并可能抛出异常 - 不要问为什么?我怀疑这个FTP例程是由一个不知道发生了什么或写得不好的人编写的,请看一下登录方法 - 所有小写字母都是上面提到的(赞成指出来)。
希望这有助于快乐寻找虫子... 最好的祝福, 汤姆。
答案 6 :(得分:0)
基本上每个方法调用都是可能的候选者,包括构造函数和属性。 (它们基本上是方法调用)最后两个虽然可能是那些风险最低的(这可能是一个奇怪的实现)
我认为最合理的是ff.getLastMessage()